1
0
mirror of https://github.com/pyenv/pyenv.git synced 2025-11-08 11:33:49 -05:00

Compare commits

...

84 Commits

Author SHA1 Message Date
Anton Petrov
3f0dd1962f 2.3.8 2022-12-08 10:07:26 +03:00
Chad Crawford
48b0224aaf Add CPython 3.7.16, 3.8.16, 3.9.16 (#2550) 2022-12-08 00:26:27 +03:00
Anton Petrov
a57106c932 Merge pull request #2544 from rudisimo/master
Add CPython 3.10.9
2022-12-07 14:35:18 +03:00
Anton Petrov
189e73e5e8 Merge pull request #2549 from anton-petrov/master
Add CPython 3.11.1
2022-12-07 14:34:58 +03:00
Anton Petrov
8680247381 Add CPython 3.11.1 2022-12-07 13:43:35 +03:00
Anton Petrov
606ff454a1 Merge pull request #2545 from saaketp/3.12.0a3
Add CPython 3.12.0a3
2022-12-07 13:10:57 +03:00
Saaket Prakash
b05d15f673 Add CPython 3.12.0a3 2022-12-07 04:57:31 +05:30
Rodolfo Puig
881ba40ff4 Add CPython 3.10.9
Signed-off-by: Rodolfo Puig <rodolfo@puig.io>
2022-12-06 17:36:03 -05:00
Anton Petrov
58bbbf8880 Merge pull request #2540 from ianchen-tw/detect-shell
Export detected shell environment in pyenv-init
2022-12-02 18:07:11 +03:00
Ian Chen
c1674cd552 Detect shell 2022-12-02 00:22:50 +08:00
Anton Petrov
74f923b5fc 2.3.7 2022-12-01 10:16:53 +03:00
Anton Petrov
59c560893a 2.3.7 2022-12-01 10:15:45 +03:00
spookyuser
4971d9e35e Copy auto installer oneliner to README (#2538) 2022-11-29 23:00:22 +03:00
weensy
6d13db992f Fix typo in README.md (#2535)
There was a space at the beginning of the `git clone` command
2022-11-28 19:43:11 +03:00
Ivan Pozdeev
13d8568620 Add 3.11 into CI for Linux 2022-11-19 00:08:53 +03:00
Isaac Levy
cc56f76733 Add --no-push-path option (#2526)
In some advanced shell setups, the order of custom-added PATH entries is important.
We disregard it by default, always pushing shims to the front of PATH,
to ensure that Pyenv works even in poorly maintained shell environments
and with minimal hassle for non-export users
(an attempt to do the opposite (#1898) has ended in a disaster).
Some advanced users are however ready and able to carefully maintain their environment
and deal with breakages and inconvenience. This option is for them.
2022-11-19 00:01:59 +03:00
Saaket Prakash
4c261e6ea1 Add CPython 3.12.0a2 (#2527) 2022-11-16 00:10:34 +03:00
native-api
31355676f0 Support aria2c being a snap (#2528)
Likely in Ubuntu where it's only available as a snap
2022-11-15 20:57:04 +03:00
Alex Hedges
c162dcd932 Add .editorconfig (#2518) 2022-11-13 05:35:45 +03:00
native-api
0b6320d371 Merge pull request #2520 from twangboy/fix_3.9.15
Fix compilation error when building OpenSSL 1.1.1q in MacOS 11+ for 3.9.15 and 3.8.15
2022-11-13 04:52:37 +03:00
Twangboy
3bfaa33c1b Gitignore special files of PyCharm and Vim 2022-11-13 04:47:01 +03:00
Twangboy
cd2858aa17 Fix compilation error when building OpenSSL 1.1.1q in MacOS 11+ for 3.9.15 and 3.8.15 2022-11-13 04:46:48 +03:00
James Campbell
19359de7b8 Add activate.nu to shim creation exception list (#2524) 2022-11-10 18:58:04 +03:00
Alex
8dd46e3915 GitHub Workflows security hardening (#2511)
Signed-off-by: Alex <aleksandrosansan@gmail.com>
2022-11-10 04:46:55 +03:00
native-api
ed1083ec27 Fix resolution of a name that's a prefix of another name (#2521) 2022-11-10 04:46:14 +03:00
Ivan Pozdeev
904fe964b0 README: Prefix auto-resolution: improve phrasing 2022-11-07 04:46:44 +03:00
Hoàng
036fd63bbd style: convert crlf to lf (#2517) 2022-11-06 19:18:04 +03:00
native-api
1250d7dd30 Don't use Zlib from XCode SDK if a custom compiler is used (#2516) 2022-11-05 02:11:55 +03:00
Omer Korner
ad6a950734 Add Python version 3.11 to the macOS build (#2510) 2022-11-03 15:32:52 +01:00
Rust Saiargaliev
6da0e89207 2.3.6 2022-11-03 09:26:31 +01:00
Ivan Pozdeev
e03118235a Improve prefix resolution documentation 2022-10-30 21:38:06 +03:00
Rust Saiargaliev
a8f921ce4d Document the release process (#2503) 2022-10-30 12:42:20 +03:00
Ivan Pozdeev
4a031504db Document prefix auto-resolution et al.
* Document listing available versions in the tutorial (#1677)
* Reflect 3.7.15's extended support
* Document using development head with Homebrew
* Structurize the Upgrading section
* Fix Pyenv-latest documentation
2022-10-30 05:28:53 +03:00
Ivan Pozdeev
75022d5d7c Revert version auto-resolution in python-build
It was moved to `pyenv-install`
2022-10-30 04:12:42 +03:00
native-api
a12f947cc3 Auto-resolve prefixes to the latest version (#2487) 2022-10-30 03:38:40 +03:00
native-api
0b5e16add3 Fix invalid syntax error in pyenv init - if PYENV_ROOT has spaces (#2506) 2022-10-29 23:08:02 +03:00
native-api
5b0ac41dec Discover Tcl/Tk from Homebrew via pkgconfig for 3.11+ (#2501)
CPython 3.11+ dropped support for --with-tcl-tk-*
in favor of pure pkgconfig
2022-10-29 22:48:13 +03:00
Michael Šimáček
44510a68f1 Add graalpy-22.3.0 (#2497) 2022-10-27 02:55:27 +03:00
Edgar R. M
16c4924f22 Add CPython 3.12.0a1 (#2495) 2022-10-27 02:41:30 +03:00
native-api
ac30d5f4e4 Merge pull request #2500 from native-api/fix_macos_openssl_build
Fix compilation error when building OpenSSL 1.1.1q in MacOS 11+
2022-10-27 00:22:09 +03:00
Ivan Pozdeev
9f5dcbffd4 Fix compilation error when building OpenSSL 1.1.1q in MacOS 11+
"error: implicitly declaring library function 'memcmp'"
Downstream backport of https://github.com/openssl/openssl/issues/18720
2022-10-27 00:02:24 +03:00
Ivan Pozdeev
faceb4b79c Allow patching supplementary packages 2022-10-27 00:02:13 +03:00
Igor Davydenko
d7389c10ee Update Python 3.11.0 tgz checksum (#2496)
For some reason checksum for `Python-3.11.0.tgz` file introduced in
0726e02e3a is invalid. Update that
checksum to ensure `pyenv install 3.11.0` works well on systems without
tar.xz support.
2022-10-26 21:21:53 +03:00
Noam Cohen
0726e02e3a Add CPython 3.11.0 (#2493) 2022-10-24 22:49:48 +03:00
Adam Johnson
03a5d65387 Add CPython 3.7.15, 3.8.15, and 3.9.15 (#2482)
Co-authored-by: Ivan Pozdeev <vano@mail.mipt.ru>
2022-10-12 20:52:53 +03:00
MuX
776f6ff9fa Add CPython 3.10.8 (#2480) 2022-10-12 07:39:42 +03:00
Ivan Pozdeev
bb0f2ae1a7 Merge branch 'master' of https://github.com/pyenv/pyenv 2022-10-08 20:49:53 +03:00
Ivan Pozdeev
ea6085e3f3 2.3.5 2022-10-08 20:49:49 +03:00
Ville Skyttä
2c2619a49e Add Pyston 2.3.5 (#2476) 2022-10-05 20:52:20 +03:00
native-api
1f526edbdd Merge pull request #2471 from native-api/add_dsymutil
Build CPython 3.12+ with --with-dsymutil in MacOS
2022-09-23 16:37:19 +03:00
Ivan Pozdeev
8b226c9679 Build 3.12+ with --with-dsymutil 2022-09-23 16:16:17 +03:00
Ivan Pozdeev
f3521e88be Allow to build CPython with --with-dsymutil
Since 3.12, CPython can provide debug symbols in
Apple's nonstandard way, "dSYM bundles"
2022-09-23 16:16:17 +03:00
native-api
5b08a6492b Add missing patch for 3.7.14 (#2469) 2022-09-22 10:59:03 +03:00
Nikita Sobolev
d722f059a0 Drop Travis integration (#2468)
It has been unused since Travis dropped free plans
2022-09-22 10:32:50 +03:00
native-api
093d0b3a49 Merge pull request #2464 from samdoran/skip-brew
Add ability to easily skip all use of Homebrew
2022-09-19 00:59:55 +03:00
Ivan Pozdeev
73d4f3102a Allow to test python-build separately 2022-09-19 00:19:01 +03:00
Ivan Pozdeev
aa07a3a37c Remove extraneous is_mac call 2022-09-19 00:19:00 +03:00
Sam Doran
e6446555f3 Add envvar to skip Homebrew 2022-09-19 00:19:00 +03:00
native-api
c5e0d2cd94 Document extended support for 3.7.14
Added in https://github.com/pyenv/pyenv/pull/2463
2022-09-15 22:01:05 +03:00
Sam Doran
cfe684ef42 Add patches for 3.7.14 needed for Apple Silicon (#2463) 2022-09-15 17:53:22 +03:00
Viktor Haag
1d28067353 Add CPython 3.11.0rc2 (#2459) 2022-09-14 07:53:34 +03:00
Tsuki
0740fdf910 Update miniconda3-3.9-4.12.0 (#2460)
update checksum from https://repo.anaconda.com/miniconda/
Miniconda3-py39_4.12.0-MacOSX-arm64.sh	52.2M	2022-06-01 14:45:20	f7448cfeb278f2a84ed903db02d5525c
2022-09-14 07:48:12 +03:00
Anton Petrov
75fc9f6fd4 Merge pull request #2456 from edgarrmondragon/cpython-3.7.14_3.8.14_3.9.14
Add CPython security releases 3.7.14, 3.8.14 and 3.9.14
2022-09-11 19:47:51 +03:00
Edgar Ramírez Mondragón
a0fbdad292 Add CPython security releases 3.7.14, 3.8.14 and 3.9.14 2022-09-07 11:13:11 -05:00
Grzegorz
6a104f68d0 docs: Add configuration option for Fish 3.2.0+ (#2449)
The original instructions were added 2 years ago in 0f2d659732. Since then, [Fish released](https://github.com/fish-shell/fish-shell/releases/tag/3.2.0) [a more declarative instruction for this operation](https://fishshell.com/docs/current/cmds/fish_add_path.html), which is now the recommended way of manipulating `PATH` in Fish.
2022-09-06 21:39:31 +03:00
Edgar R. M
f6f1803ac9 Add CPython 3.10.7 (#2454) 2022-09-06 19:13:59 +03:00
Ivan Pozdeev
23559ee6d1 Fix syntax error 2022-09-06 01:43:12 +03:00
Ivan Pozdeev
4e31668c21 Ignore beta and release candidates in :latest
Fixes https://github.com/pyenv/pyenv/issues/2450
2022-09-05 23:20:39 +03:00
Ivan Pozdeev
2b22145670 2.3.4 2022-09-04 01:54:33 +03:00
Filip Š
7c1c180551 Add Cinder 3.8 (#2433)
* Add Cinder 3.8
* Add distro and GCC warnings
* Set the complier to GCC 10 if available

Co-authored-by: Ivan Pozdeev <vano@mail.mipt.ru>
2022-09-04 01:48:43 +03:00
native-api
a648682ed6 CI: Bump OS versions (#2448)
* CI: Bump OS versions

Github released ubuntu-22.04 and macos-12 from beta
and deprecated ubuntu-18.04 and macos-10.15, due to dropping by 2013.

* CI: clean up installed packages
2022-09-04 01:40:00 +03:00
James Stronz
47b0ce77c0 Re-allow paths in .python-version provided that they resolve to within the versions dir (#2442)
* Fixes #2430 while still preventing CVE-2022-35861
* Adds a skipped version message to stderr

Co-authored-by: Ivan Pozdeev <vano@mail.mipt.ru>
2022-09-03 22:37:53 +03:00
Ivan Pozdeev
fdabd14c2b Merge branch 'master' of https://github.com/pyenv/pyenv 2022-09-03 22:31:15 +03:00
Ivan Pozdeev
e52ad61389 CI: Bump versions 2022-09-03 22:31:00 +03:00
native-api
2e5983b004 Merge pull request #2447 from native-api/ci_modified_micropython
CI: support Micropython, deleted scripts; build with -v
2022-09-03 22:22:56 +03:00
Ivan Pozdeev
27b5f62dfb CI: Build with -v 2022-09-03 22:02:47 +03:00
Ivan Pozdeev
7c1e3a710c CI: Support Micropython 2022-09-03 22:02:47 +03:00
Ivan Pozdeev
13f273188d CI: Exclude deleted scripts from modified check 2022-09-03 22:02:47 +03:00
Dmitriy Serdyuk
c89a69a6ed Add micropython 1.18 and 1.19.1 (#2443)
Support frozen builtin modules e.g. upip
2022-09-01 13:48:26 +03:00
native-api
a8afc61146 CONTRIBUTING.md: phrasing 2022-08-16 21:33:49 +03:00
native-api
e4a0c12b1b CONTRIBUTING.md: clarify that Bash 4+ optimizations are allowed 2022-08-16 21:32:14 +03:00
hardikpnsp
afeb971fa2 Add support for multiple versions in pyenv uninstall (#2432) 2022-08-15 20:25:46 +03:00
Edgar R. M
965421d5d4 Add CPython 3.11.0rc1 (#2434) 2022-08-14 15:12:22 +03:00
Janith Petangoda
ae22c69505 Small update to instruction in README.md (#2431) 2022-08-06 18:12:11 +03:00
73 changed files with 2585 additions and 444 deletions

11
.editorconfig Normal file
View File

@@ -0,0 +1,11 @@
# Editor configuration, see https://editorconfig.org
root = true
[*]
end_of_line = lf
charset = utf-8
# Makefiles always use tabs for indentation
[Makefile]
indent_style = tab
indent_size = unset # Allow user-defined tab width

View File

@@ -1,16 +1,21 @@
name: macos_build
on: [pull_request, push]
permissions:
contents: read # to fetch code (actions/checkout)
jobs:
macos_build:
strategy:
fail-fast: false
matrix:
python-version:
- 3.7.10
- 3.8.10
- 3.9.5
- 3.10.0
runs-on: macos-10.15
- "3.7"
- "3.8"
- "3.9"
- "3.10"
- "3.11"
runs-on: macos-11
steps:
- uses: actions/checkout@v2
# Normally, we would use the superbly maintained...
@@ -27,7 +32,7 @@ jobs:
run: |
echo $PYENV_ROOT
echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH
bin/pyenv install ${{ matrix.python-version }}
bin/pyenv install -v ${{ matrix.python-version }}
bin/pyenv global ${{ matrix.python-version }}
bin/pyenv rehash
- run: python --version

View File

@@ -12,7 +12,7 @@ jobs:
run: >
versions=$(git diff "origin/$GITHUB_BASE_REF" --name-only -z
| perl -ne 'BEGIN {$\="\n";$/="\0";} chomp;
if (/^plugins\/python-build\/share\/python-build\/(?:([^\/]+)|patches\/([^\/]+)\/.*)$/)
if (/^plugins\/python-build\/share\/python-build\/(?:([^\/]+)|patches\/([^\/]+)\/.*)$/ and -e $& )
{ print $1.$2; }' \
| sort -u);
echo -e "versions<<!\\n$versions\\n!" >> $GITHUB_ENV
@@ -27,7 +27,7 @@ jobs:
fail-fast: false
matrix:
python-version: ${{fromJson(needs.discover_modified_scripts.outputs.versions)}}
os: ["macos-10.15", "macos-11"]
os: ["macos-11", "macos-12"]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
@@ -38,22 +38,33 @@ jobs:
echo "PYENV_ROOT=$PYENV_ROOT" >> $GITHUB_ENV
echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH
- run: |
pyenv install ${{ matrix.python-version }}
pyenv install -v ${{ matrix.python-version }}
pyenv global ${{ matrix.python-version }}
- run: |
python --version
python -m pip --version
- shell: python # Prove that actual Python == expected Python
env:
# Micropython doesn't support --version
- run: >
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: |
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
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
# bundled executables in some Anaconda releases cause the post-run step to hang in MacOS
- run: |
pyenv global system
@@ -66,32 +77,44 @@ jobs:
fail-fast: false
matrix:
python-version: ${{fromJson(needs.discover_modified_scripts.outputs.versions)}}
os: ["ubuntu-18.04", "ubuntu-20.04"]
os: ["ubuntu-20.04", "ubuntu-22.04"]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- run: |
sudo apt-get update -q; sudo apt-get install -yq build-essential \
sudo apt-get update -q; sudo apt-get install -yq 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
curl llvm libncurses5-dev libncursesw5-dev \
xz-utils tk-dev libffi-dev liblzma-dev
- run: |
export PYENV_ROOT="$GITHUB_WORKSPACE"
echo "PYENV_ROOT=$PYENV_ROOT" >> $GITHUB_ENV
echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH
- run: |
pyenv install ${{ matrix.python-version }}
pyenv install -v ${{ matrix.python-version }}
pyenv global ${{ matrix.python-version }}
- run: python --version
- run: python -m pip --version
- shell: python # Prove that actual Python == expected Python
env:
# Micropython doesn't support --version
- run: >
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: |
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
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

View File

@@ -1,26 +1,30 @@
name: No Response
# Both `issue_comment` and `scheduled` event types are required for this Action
# to work properly.
on:
issue_comment:
types: [created]
schedule:
# Schedule for ten minutes after the hour, every hour
- cron: '10 * * * *'
jobs:
noResponse:
runs-on: ubuntu-latest
steps:
- uses: lee-dohm/no-response@v0.5.0
with:
token: ${{ github.token }}
daysUntilClose: 30
responseRequiredLabel: need-feedback
closeComment: >
This issue has been automatically closed because there has been no response
to our request for more information from the original author. With only the
information that is currently in the issue, we don't have enough information
to take action. Please reach out if you have or find the answers we need so
that we can investigate further.
name: No Response
# Both `issue_comment` and `scheduled` event types are required for this Action
# to work properly.
on:
issue_comment:
types: [created]
schedule:
# Schedule for ten minutes after the hour, every hour
- cron: '10 * * * *'
permissions: {}
jobs:
noResponse:
permissions:
issues: write # to update issues (lee-dohm/no-response)
runs-on: ubuntu-latest
steps:
- uses: lee-dohm/no-response@v0.5.0
with:
token: ${{ github.token }}
daysUntilClose: 30
responseRequiredLabel: need-feedback
closeComment: >
This issue has been automatically closed because there has been no response
to our request for more information from the original author. With only the
information that is currently in the issue, we don't have enough information
to take action. Please reach out if you have or find the answers we need so
that we can investigate further.

View File

@@ -1,15 +1,19 @@
name: pyenv_tests
on: [pull_request, push]
permissions:
contents: read # to fetch code (actions/checkout)
jobs:
pyenv_tests:
strategy:
fail-fast: false
matrix:
os:
- ubuntu-22.04
- ubuntu-20.04
- ubuntu-18.04
- macos-12
- macos-11
- macos-10.15
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2

View File

@@ -1,16 +1,21 @@
name: ubuntu_build
on: [pull_request, push]
permissions:
contents: read # to fetch code (actions/checkout)
jobs:
ubuntu_build:
strategy:
fail-fast: false
matrix:
python-version:
- 3.7.10
- 3.8.10
- 3.9.5
- 3.10.0
runs-on: Ubuntu-20.04
- "3.7"
- "3.8"
- "3.9"
- "3.10"
- "3.11"
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
# Normally, we would use the superbly maintained...
@@ -19,9 +24,9 @@ jobs:
# 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
sudo apt-get install -yq make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev curl \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
# https://github.com/pyenv/pyenv#installation
- run: pwd
- env:
@@ -29,7 +34,7 @@ jobs:
run: |
echo $PYENV_ROOT
echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH
bin/pyenv install ${{ matrix.python-version }}
bin/pyenv install -v ${{ matrix.python-version }}
bin/pyenv global ${{ matrix.python-version }}
bin/pyenv rehash
- run: python --version

2
.gitignore vendored
View File

@@ -8,3 +8,5 @@
/src/*.o
/bats/
/default-packages
.idea
*.un~

View File

@@ -1,83 +0,0 @@
# Two types of tests:
#
# 1. shell tests run using bats
# 2. build tests also run using bats
#
# Shell tests are run unconditionally on Linux (see jobs.include).
#
# Build tests can be skipped by starting the commit message with
# '[skip build]'.
#
# Build tests are run on platforms generated from all combinations
# of keys below.
language: c
os:
- linux
- osx
dist:
- focal
# https://docs.travis-ci.com/user/reference/osx/#macos-version
osx_image:
- xcode9.4.1 # macOS 10.13.6
- xcode10.3 # macOS 10.14.4
- xcode11.6 # macOS 10.15.7
- xcode12.2 # macOS 10.15.7
env:
- PYTHON_BUILD_VERSION=3.9.1
- PYTHON_BUILD_VERSION=3.7.5
before_install:
- date +%Y-%m-%dT%H:%M:%S
install: git clone --depth 1 --branch v1.2.0 https://github.com/bats-core/bats-core.git bats
# Default for auto-generated jobs.
script: make test-build
jobs:
include:
# Shell-based tests should execute every time.
- stage: test shell
script: make test
env: PYENV_NATIVE_EXT=1
after_script: []
os: linux
- stage: test shell
script: make test
env: PYENV_NATIVE_EXT=
after_script: []
os: linux
exclude:
# For each osx_image but one there should be an entry in the exclude
# list, to prevent duplicate Linux builds.
- os: linux
osx_image: xcode9.4
- os: linux
osx_image: xcode10
allow_failures:
- env: PYTHON_BUILD_VERSION=3.9.1
stages:
- test shell
- name: test
if: NOT (commit_message =~ /^\[skip build\]/)
# Default
notifications:
email:
on_success: never
deploy:
provider: releases
api_key:
secure: FLWevL09KYp7V1SjJUNEdWzuomuocXwNvPr1DSAFH7mmrjKTtjzwrjINAthSqzjlDrs5B//P47l1VLyHp5byEzy673W+bOmEg8swmqc7E9FrHLRyEByd/yca3DzkZgXEXgGdY/cl7tHhM4V2fYKEgAIWbFV+takmTFMK4WkEtNg=
on:
repo: pyenv/pyenv
tags: true

View File

@@ -1,4 +1,67 @@
## Version History
# Version History
## Release 2.3.8
* Export detected shell environment in pyenv-init by @ianchen-tw in https://github.com/pyenv/pyenv/pull/2540
* Add CPython 3.12.0a3 by @saaketp in https://github.com/pyenv/pyenv/pull/2545
* Add CPython 3.11.1 by @anton-petrov in https://github.com/pyenv/pyenv/pull/2549
* Add CPython 3.10.9 by @rudisimo in https://github.com/pyenv/pyenv/pull/2544
* Add 3.7.16, 3.8.16, 3.9.16 by @chadac in https://github.com/pyenv/pyenv/pull/2550
## Release 2.3.7
* Add Python version 3.11 to the macOS build by @jbkkd in https://github.com/pyenv/pyenv/pull/2510
* Don't use Zlib from XCode SDK if a custom compiler is used by @native-api in https://github.com/pyenv/pyenv/pull/2516
* Change line endings from CRLF to LF by @hoang-himself in https://github.com/pyenv/pyenv/pull/2517
* Fix resolution of a name that's a prefix of another name by @native-api in https://github.com/pyenv/pyenv/pull/2521
* GitHub Workflows security hardening by @sashashura in https://github.com/pyenv/pyenv/pull/2511
* Add nushell to activate list by @theref in https://github.com/pyenv/pyenv/pull/2524
* Fix compilation error when building OpenSSL 1.1.1q in MacOS 11+ for 3.9.15 and 3.8.15 by @twangboy in https://github.com/pyenv/pyenv/pull/2520
* Add simple `.editorconfig` file by @aphedges in https://github.com/pyenv/pyenv/pull/2518
* Support `aria2c` being a snap by @native-api in https://github.com/pyenv/pyenv/pull/2528
* Add CPython 3.12.0a2 by @saaketp in https://github.com/pyenv/pyenv/pull/2527
* Add --no-push-path option by @isaacl in https://github.com/pyenv/pyenv/pull/2526
* Fix typo in README.md by @weensy in https://github.com/pyenv/pyenv/pull/2535
* Copy auto installer oneliner to readme by @spookyuser in https://github.com/pyenv/pyenv/pull/2538
## Release 2.3.6
* Add CPython 3.10.8 (#2480)
* Add CPython 3.7.15, 3.8.15, and 3.9.15 (#2482)
* Add CPython 3.11.0 (#2493)
* Add CPython 3.12.0a1 (#2495)
* Add graalpy-22.3.0 (#2497)
* Auto-resolve prefixes to the latest version (#2487)
* It must be a full prefix -- the actual searched prefix is `<prefix>[-.]`
* Other flavors are likely sorted incorrectly atm
* Prereleases and versions with some suffixes (`-dev`, `-src`, `-latest`) are not searched
* `pyenv uninstall` has been excluded from the resolution feature: deleting a dynamically selected installation could be problematic
* Fix OpenSSL 1.1.1q compilation error in MacOS 11+ (#2500)
* Link to Tcl/Tk from Homebrew via pkgconfig for 3.11+ (#2501)
* Fix syntax error in `pyenv init -` if PYENV_ROOT has spaces (#2506)
## Release 2.3.5
* Add CPython 3.10.7 (#2454)
* Docs: update Fish PATH update (#2449)
* Add CPython 3.7.14, 3.8.14 and 3.9.14 (#2456)
* Update miniconda3-3.9-4.12.0 (#2460)
* Add CPython 3.11.0rc2 (#2459)
* Add patches for 3.7.14 to support Apple Silicon (#2463)
* Add ability to skip all use of Homebrew (#2464)
* Drop Travis integration (#2468)
* Build CPython 3.12+ with --with-dsymutil in MacOS (#2471)
* Add Pyston 2.3.5 (#2476)
## Release 2.3.4
* Add CPython 3.11.0rc1 (#2434)
* Add support for multiple versions in `pyenv uninstall` (#2432)
* Add micropython 1.18 and 1.19.1 (#2443)
* CI: support Micropython, deleted scripts; build with -v (#2447)
* Re-allow paths in .python-version while still preventing CVE-2022-35861 (#2442)
* CI: Bump OS versions (#2448)
* Add Cinder 3.8 (#2433)
## Release 2.3.3

View File

@@ -20,6 +20,7 @@ The most common subcommands are:
* [`pyenv exec`](#pyenv-exec)
* [`pyenv root`](#pyenv-root)
* [`pyenv prefix`](#pyenv-prefix)
* [`pyenv latest`](#pyenv-latest)
* [`pyenv hooks`](#pyenv-hooks)
* [`pyenv shims`](#pyenv-shims)
* [`pyenv init`](#pyenv-init)
@@ -228,7 +229,13 @@ Then install the desired versions:
2.6.8
* 2.7.6 (set by /home/yyuu/.pyenv/version)
To install the latest version of Python without giving a specific version use the `:latest` syntax. For example, to install the latest patch version for Python 3.8 you could do:
You can also install the latest version of Python in a specific version line by supplying a prefix instead of a complete name:
$ pyenv install 3.10
See the [`pyenv latest` documentation](#pyenv-latest) for details on prefix resolution.
An older option is to use the `:latest` syntax. For example, to install the latest patch version for Python 3.8 you could do:
pyenv install 3.8:latest
@@ -238,9 +245,9 @@ To install the latest major release for Python 3 try:
## `pyenv uninstall`
Uninstall a specific Python version.
Uninstall Python versions.
Usage: pyenv uninstall [-f|--force] <version>
Usage: pyenv uninstall [-f|--force] <version> ...
-f Attempt to remove the specified version without prompting
for confirmation. If the version does not exist, do not
@@ -330,6 +337,19 @@ locations of the currently selected versions.
$ pyenv prefix 3.9.7
/home/user/.pyenv/versions/3.9.7
## `pyenv latest`
Displays the latest installed or known version with the given prefix
Usage: pyenv latest [-k|--known] [-q|--quiet] <prefix>
-k/--known Select from all known versions instead of installed
-q/--quiet Do not print an error message on resolution failure
Only full prefixes are searched: in the actual name, the given prefix must be followed by a dot or a dash.
Prereleases and versions with specific suffixes (e.g. `-src`) are ignored.
## `pyenv hooks`
Lists installed hook scripts for a given pyenv command.
@@ -366,11 +386,12 @@ List existing pyenv shims.
Configure the shell environment for pyenv
Usage: eval "$(pyenv init [-|--path] [--no-rehash] [<shell>])"
Usage: eval "$(pyenv init [-|--path] [--no-push-path] [--no-rehash] [<shell>])"
- Initialize shims directory, print PYENV_SHELL variable, completions path
and shell function
--path Print shims path
--no-push-path Do not push shim to the start of PATH if they're already there
--no-rehash Add no rehash command to output
## `pyenv completions`

View File

@@ -1,106 +1,109 @@
General guidance
================
* The usual principles of respecting existing conventions and making sure that your changes
are in line with the overall product design apply when contributing code to Pyenv.
* We are limited to Bash 3.2 features
That's because that's the version shipped with MacOS.
(They didn't upgrade past it and switched to Zsh because later versions
are covered by GPLv3 which has additional restrictions unacceptable for Apple.)
* 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
==============
We strive to keep commit history one-concern-per-commit to keep it meaningful and easy to follow.
If a pull request (PR) addresses a single concern (the typical case), we usually squash commits
from it together when merging so its commit history doesn't matter.
If however a PR addresses multiple separate concerns, each of them should be presented as a separate commit.
Adding multiple new Python releases of the same flavor is okay with either a single or multiple commits.
Authoring installation scripts
==============================
Adding new Python release support
---------------------------------
The easiest way to add support for a new Python release is to copy the script from the previous one
and adjust it as necessary. In many cases, just changing version numbers, URLs and hashes is enough.
Do pay attention to other "magic numbers" that may be present in a script --
e.g. the set of architectures and OS versions supported by a release -- since those change from time to time, too.
Make sure to also copy any patches for the previous release that still apply to the new one.
Typically, a patch no longer applies if it addresses a problem that's already fixed in the new release.
For prereleases, we only create an entry for the latest prerelease in a specific version line.
When submitting a newer prerelease, replace the older one.
Adding version-specific fixes/patches
-------------------------------------
We accept fixes to issues in specific Python releases that prevent users from using them with Pyenv.
In the default configuration for a Python release, we strive to provide as close to vanilla experience as practical,
to maintain [the principle of the least surprise](https://en.wikipedia.org/wiki/Principle_of_least_astonishment).
As such, any such fixes:
* Must not break or degrade (e.g. disable features) the build in any of the environments that the release officially supports
* Must not introduce incompatibilities with the vanilla release (including binary incompatibilities)
* Should not patch things unnecessarily, to minimize the risk of the aforementioned undesirable side effects.
* E.g. if the fix is for a specific environment, its logic ought to only fire in this specific environment and not touch execution paths for other environments.
* As such, it's advisable to briefly explain in the PR what each added patch does and why it is necessary to fix the declared problem
Generally, version-specific fixes belong in the scripts for the affected releases and/or patches for them -- this guarantees that their effect is limited to only those releases.
<h3>Backporting upstream patches</h3>
Usually, this is the easiest way to backport a fix for a problem that is fixed in a newer release.
* Clone Python, check out the tag for the appropriate release and create a branch
* Apply existing patches if there are any (with either `patch` or `git am`) and commit
* Cherry-pick the upstream commit that fixes the problem in a newer release
* Commit and `git format-patch`
* Commit the generated patch file into Pyenv, test your changes and submit a PR
Deprecation policy
------------------
We do not provide official support for EOL releases and environments or otherwise provide any kind of extended support for old Python releases.
We do however accept fixes from interested parties that would allow running older, including EOL, releases in newer environments.
In addition to the above requirements for release-specific fixes,
* Such a fix must not add maintenance burden (e.g. add new logic to `python-build` that has to be kept there indefinitely)
* Unless the added logic is useful for both EOL and non-EOL releases. In this case, it will be considered as being primarily an improvement for non-EOL releases.
* Support is provided on a "best effort" basis: we do not maintain these fixes but won't actively break them, either, and accept any corrections.
Since old releases never change, it's pretty safe to assume that the fixes will continue to work until a later version
of an environment introduces further incompatible changes.
Advanced changes / adding new Python flavor support
---------------------------------------------------
An installation script is sourced from `python-build`. All installation scripts are based on the same logic:
1. Select the source to download and other variable parameters as needed.
This includes showing an error if the user's environment (OS, architecture) is not supported by the release.
Binary releases that only officially support specific distro(s) typically show a warning in other distros instead.
2. Run one of the `install_*` shell functions
`install_*` shell functions defined in `python-build` install Python from different kinds of sources -- compressed package (binary or source), upstream installation script, VCS checkout. Pick one that's the most appropriate for your packaging.
Each of them accepts a couple of function-specific arguments which are followed by arguments that constitute the build sequence. Each `<argument>` in the build sequence corresponds to the `install_*_<argument>` function in `python-build`. Check what's available and add any functions with logic specific to your flavor if needed.
We strive to keep out of `python-build` parts of build logic that are release-specific and/or tend to change abruptly between releases -- e.g. sets of supported architectures and other software's versions. This results in logic duplication between installation scripts -- but since old releases never change once released, this doesn't really add to the maintenance burden. As a rule of thumb, `python-build` can host parts of logic that are expected to stay the same for an indefinite amount of time -- for an entire Python flavor or release line.
General guidance
================
* The usual principles of respecting existing conventions and making sure that your changes
are in line with the overall product design apply when contributing code to Pyenv.
* We are limited to Bash 3.2 features
That's because that's the version shipped with MacOS.
(They didn't upgrade past it and switched to Zsh because later versions
are covered by GPLv3 which has additional restrictions unacceptable for Apple.)
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.
* 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
==============
We strive to keep commit history one-concern-per-commit to keep it meaningful and easy to follow.
If a pull request (PR) addresses a single concern (the typical case), we usually squash commits
from it together when merging so its commit history doesn't matter.
If however a PR addresses multiple separate concerns, each of them should be presented as a separate commit.
Adding multiple new Python releases of the same flavor is okay with either a single or multiple commits.
Authoring installation scripts
==============================
Adding new Python release support
---------------------------------
The easiest way to add support for a new Python release is to copy the script from the previous one
and adjust it as necessary. In many cases, just changing version numbers, URLs and hashes is enough.
Do pay attention to other "magic numbers" that may be present in a script --
e.g. the set of architectures and OS versions supported by a release -- since those change from time to time, too.
Make sure to also copy any patches for the previous release that still apply to the new one.
Typically, a patch no longer applies if it addresses a problem that's already fixed in the new release.
For prereleases, we only create an entry for the latest prerelease in a specific version line.
When submitting a newer prerelease, replace the older one.
Adding version-specific fixes/patches
-------------------------------------
We accept fixes to issues in specific Python releases that prevent users from using them with Pyenv.
In the default configuration for a Python release, we strive to provide as close to vanilla experience as practical,
to maintain [the principle of the least surprise](https://en.wikipedia.org/wiki/Principle_of_least_astonishment).
As such, any such fixes:
* Must not break or degrade (e.g. disable features) the build in any of the environments that the release officially supports
* Must not introduce incompatibilities with the vanilla release (including binary incompatibilities)
* Should not patch things unnecessarily, to minimize the risk of the aforementioned undesirable side effects.
* E.g. if the fix is for a specific environment, its logic ought to only fire in this specific environment and not touch execution paths for other environments.
* As such, it's advisable to briefly explain in the PR what each added patch does and why it is necessary to fix the declared problem
Generally, version-specific fixes belong in the scripts for the affected releases and/or patches for them -- this guarantees that their effect is limited to only those releases.
<h3>Backporting upstream patches</h3>
Usually, this is the easiest way to backport a fix for a problem that is fixed in a newer release.
* Clone Python, check out the tag for the appropriate release and create a branch
* Apply existing patches if there are any (with either `patch` or `git am`) and commit
* Cherry-pick the upstream commit that fixes the problem in a newer release
* Commit and `git format-patch`
* Commit the generated patch file into Pyenv, test your changes and submit a PR
Deprecation policy
------------------
We do not provide official support for EOL releases and environments or otherwise provide any kind of extended support for old Python releases.
We do however accept fixes from interested parties that would allow running older, including EOL, releases in newer environments.
In addition to the above requirements for release-specific fixes,
* Such a fix must not add maintenance burden (e.g. add new logic to `python-build` that has to be kept there indefinitely)
* Unless the added logic is useful for both EOL and non-EOL releases. In this case, it will be considered as being primarily an improvement for non-EOL releases.
* Support is provided on a "best effort" basis: we do not maintain these fixes but won't actively break them, either, and accept any corrections.
Since old releases never change, it's pretty safe to assume that the fixes will continue to work until a later version
of an environment introduces further incompatible changes.
Advanced changes / adding new Python flavor support
---------------------------------------------------
An installation script is sourced from `python-build`. All installation scripts are based on the same logic:
1. Select the source to download and other variable parameters as needed.
This includes showing an error if the user's environment (OS, architecture) is not supported by the release.
Binary releases that only officially support specific distro(s) typically show a warning in other distros instead.
2. Run one of the `install_*` shell functions
`install_*` shell functions defined in `python-build` install Python from different kinds of sources -- compressed package (binary or source), upstream installation script, VCS checkout. Pick one that's the most appropriate for your packaging.
Each of them accepts a couple of function-specific arguments which are followed by arguments that constitute the build sequence. Each `<argument>` in the build sequence corresponds to the `install_*_<argument>` function in `python-build`. Check what's available and add any functions with logic specific to your flavor if needed.
We strive to keep out of `python-build` parts of build logic that are release-specific and/or tend to change abruptly between releases -- e.g. sets of supported architectures and other software's versions. This results in logic duplication between installation scripts -- but since old releases never change once released, this doesn't really add to the maintenance burden. As a rule of thumb, `python-build` can host parts of logic that are expected to stay the same for an indefinite amount of time -- for an entire Python flavor or release line.

15
MAINTENANCE.md Normal file
View File

@@ -0,0 +1,15 @@
Creating a release
==================
The release of the new version of Pyenv is done via GitHub Releases.
Release checklist:
* Start [drafting a new release on GitHub](https://github.com/pyenv/pyenv/releases) to generate a summary of changes. Save the summary locally.
* 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)
* 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).
* Major version is pushed if there are breaking changes
* Update `CHANGELOG.md` with the new version number and the edited summary (only the changes section), reformatting it like the rest of the changelog sections
* Commit the changes locally into `master`
* Create a new tag with the new version number and push the changes including the tag
* Create a new release on GitHub based on the tag, using the saved summary

View File

@@ -1,11 +1,15 @@
.PHONY: test test-build
.PHONY: test test-build test-unit test-plugin
# Do not pass in user flags to build tests.
unexport PYTHON_CFLAGS
unexport PYTHON_CONFIGURE_OPTS
test: bats
test: test-unit test-plugin
test-unit: bats
PATH="./bats/bin:$$PATH" test/run
test-plugin: bats
cd plugins/python-build && $(PWD)/bats/bin/bats $${CI:+--tap} test
PYTHON_BUILD_ROOT := $(CURDIR)/plugins/python-build

View File

@@ -53,17 +53,20 @@ This project was forked from [rbenv](https://github.com/rbenv/rbenv) and
* [Install Python build dependencies](#install-python-build-dependencies)
* **[Usage](#usage)**
* [Install additional Python versions](#install-additional-python-versions)
* [Prefix auto-resolution](#prefix-auto-resolution)
* [Python versions with extended support](#python-versions-with-extended-support)
* [Switch between Python versions](#switch-between-python-versions)
* [Uninstall Python versions](#uninstall-python-versions)
* [Other operations](#other-operations)
* [Upgrading](#upgrading)
* [Upgrading with Homebrew](#upgrading-with-homebrew)
* [Upgrading with Installer or Git checkout](#upgrading-with-installer-or-git-checkout)
* [Uninstalling pyenv](#uninstalling-pyenv)
* [Advanced Configuration](#advanced-configuration)
* [Using Pyenv without shims](#using-pyenv-without-shims)
* [Environment variables](#environment-variables)
* **[Development](#development)**
* [Contributing](#contributing)**
* [Contributing](#contributing)
* [Version History](#version-history)
* [License](#license)
@@ -244,7 +247,9 @@ which does install native Windows Python versions.
#### Automatic installer
Visit our other project:
`curl https://pyenv.run | bash`
For more details visit our other project:
https://github.com/pyenv/pyenv-installer
@@ -255,14 +260,14 @@ easy to fork and contribute any changes back upstream.
* **Check out Pyenv where you want it installed.**
A good place to choose is `$HOME/.pyenv` (but you can install it somewhere else):
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
```
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
```
* Optionally, try to compile a dynamic Bash extension to speed up Pyenv. Don't
worry if it fails; Pyenv will still work normally:
cd ~/.pyenv && src/configure && make -C src
```
cd ~/.pyenv && src/configure && make -C src
```
### Set up your shell environment for Pyenv
@@ -288,7 +293,7 @@ See [Advanced configuration](#advanced-configuration) for details and more confi
configuration commands to both `.bashrc` (for interactive shells)
and the profile file that Bash would use (for login shells).
First, add the commands to `~/.bashrc`:
First, add the commands to `~/.bashrc` by running the following in your terminal:
~~~ bash
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
@@ -324,14 +329,21 @@ See [Advanced configuration](#advanced-configuration) for details and more confi
- For **Fish shell**:
Execute this interactively:
If you have Fish 3.2.0 or newer, execute this interactively:
~~~ fish
set -Ux PYENV_ROOT $HOME/.pyenv
fish_add_path $PYENV_ROOT/bin
~~~
Otherwise, execute the snippet below:
~~~ fish
set -Ux PYENV_ROOT $HOME/.pyenv
set -U fish_user_paths $PYENV_ROOT/bin $fish_user_paths
~~~
And add this to `~/.config/fish/config.fish`:
Now, add this to `~/.config/fish/config.fish`:
~~~ fish
pyenv init - | source
@@ -376,6 +388,8 @@ For example, to download and install Python 3.10.4, run:
pyenv install 3.10.4
```
Running `pyenv install -l` gives the list of all available versions.
**NOTE:** Most Pyenv-provided Python releases are source releases and are built
from source as part of installation (that's why you need Python build dependencies preinstalled).
You can pass options to Python's `configure` and compiler flags to customize the build,
@@ -390,6 +404,25 @@ please visit the wiki page about
[Common Build Problems](https://github.com/pyenv/pyenv/wiki/Common-build-problems).
#### Prefix auto-resolution
All Pyenv subcommands except `uninstall` automatically resolve full prefixes to the latest version in the corresponding version line.
`pyenv install` picks the latest known version while other subcommands -- the latest installed version.
E.g. to install and then switch to the latest 3.10 release:
```sh
pyenv install 3.10
pyenv global 3.10
```
You can run [`pyenv latest <prefix>`](COMMANDS.md#pyenv-latest) to see
what a specific prefix would be resolved to.
See the [`pyenv latest` documentation](COMMANDS.md#pyenv-latest) for details.
#### Python versions with extended support
For the following Python releases, Pyenv applies user-provided patches that add support for some newer environments.
@@ -397,7 +430,7 @@ Though we don't actively maintain those patches, since existing releases never c
it's safe to assume that they will continue working until there are further incompatible changes
in a later version of those environments.
* *3.7.8-3.7.13, 3.8.4-3.8.12, 3.9.0-3.9.7* : XCode 13.3
* *3.7.8-3.7.15, 3.8.4-3.8.12, 3.9.0-3.9.7* : XCode 13.3
* *3.6.15* : MacOS 11+ and XCode 13.3
* *2.7.18* : MacOS 10.15+ and Apple Silicon
@@ -432,7 +465,7 @@ for more details on how the selection works and more information on its usage.
As time goes on, you will accumulate Python versions in your
`$(pyenv root)/versions` directory.
To remove old Python versions, use [`pyenv uninstall <version>`](COMMANDS.md#pyenv-uninstall).
To remove old Python versions, use [`pyenv uninstall <versions>`](COMMANDS.md#pyenv-uninstall).
Alternatively, you can simply `rm -rf` the directory of the version you want
to remove. You can find the directory of a particular Python version
@@ -452,12 +485,34 @@ Note that Pyenv plugins that you install may add their own subcommands.
## Upgrading
### Upgrading with Homebrew
If you've installed Pyenv using Homebrew, upgrade using:
```sh
brew upgrade pyenv
```
If you've installed Pyenv using Pyenv-installer or Git checkout, you can
To switch from a release to the latest development version of Pyenv, use:
```sh
brew uninstall pyenv
brew install pyenv --head
```
then you can upgrade it with `brew upgrade pyenv` as usual.
### Upgrading with Installer or Git checkout
If you've installed Pyenv with Pyenv-installer, you likely have the
[Pyenv-Update](https://github.com/pyenv/pyenv-update) plugin that would
upgrade Pyenv and all installed plugins:
```sh
pyenv update
```
If you've installed Pyenv using Pyenv-installer or Git checkout, you can also
upgrade your installation at any time using Git.
To upgrade to the latest development version of pyenv, use `git pull`:

View File

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

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash
# Summary: Configure the shell environment for pyenv
# Usage: eval "$(pyenv init [-|--path] [--no-rehash] [<shell>])"
# Usage: eval "$(pyenv init [-|--path] [--no-push-path] [--detect-shell] [--no-rehash] [<shell>])"
set -e
[ -n "$PYENV_DEBUG" ] && set -x
@@ -9,7 +9,9 @@ set -e
if [ "$1" = "--complete" ]; then
echo -
echo --path
echo --no-push-path
echo --no-rehash
echo --detect-shell
echo bash
echo fish
echo ksh
@@ -19,6 +21,7 @@ fi
mode="help"
no_rehash=""
no_push_path=""
for args in "$@"
do
if [ "$args" = "-" ]; then
@@ -30,6 +33,16 @@ do
mode="path"
shift
fi
if [ "$args" = "--detect-shell" ]; then
mode="detect-shell"
shift
fi
if [ "$args" = "--no-push-path" ]; then
no_push_path=1
shift
fi
if [ "$args" = "--no-rehash" ]; then
no_rehash=1
@@ -69,12 +82,17 @@ function main() {
print_shell_function
exit 0
;;
"detect-shell")
detect_profile
print_detect_shell
exit 0
;;
esac
# should never get here
exit 2
}
function help_() {
function detect_profile() {
case "$shell" in
bash )
if [ -e '~/.bash_profile' ]; then
@@ -98,7 +116,16 @@ function help_() {
rc='your shell'\''s interactive startup file'
;;
esac
}
function print_detect_shell() {
echo "PYENV_SHELL_DETECT=$shell"
echo "PYENV_PROFILE_DETECT=$profile"
echo "PYENV_RC_DETECT=$rc"
}
function help_() {
detect_profile
{
case "$shell" in
fish )
@@ -141,24 +168,56 @@ function init_dirs() {
}
function print_path() {
case "$shell" in
fish )
echo 'while set index (contains -i -- '\'"${PYENV_ROOT}/shims"\'' $PATH)'
echo 'set -eg PATH[$index]; end; set -e index'
echo 'set -gx PATH '\'"${PYENV_ROOT}/shims"\'' $PATH'
;;
* )
# Some distros (notably Debian-based) set Bash's SSH_SOURCE_BASHRC compilation option
# that makes it source `bashrc` under SSH even when not interactive.
# This is inhibited by a guard in Debian's stock `bashrc` but some people remove it
# in order to get proper environment for noninteractive remote commands
# (SSH provides /etc/ssh/sshrc and ~/.ssh/rc for that but no-one seems to use them for some reason).
# This has caused an infinite `bashrc` execution loop for those people in the below nested Bash invocation (#2367).
# --norc negates this behavior of such a customized Bash.
echo 'PATH="$(bash --norc -ec '\''IFS=:; paths=($PATH); for i in ${!paths[@]}; do if [[ ${paths[i]} == "'\'"${PYENV_ROOT}/shims"\''" ]]; then unset '\'\\\'\''paths[i]'\'\\\'\''; fi; done; echo "${paths[*]}"'\'')"'
echo 'export PATH="'"${PYENV_ROOT}"'/shims:${PATH}"'
;;
esac
# if no_push_path is set, guard the PATH manipulation with a check on whether
# the shim is already in the PATH.
if [ -n "$no_push_path" ]; then
case "$shell" in
fish )
echo 'if not contains -- "'"${PYENV_ROOT}/shims"'" $PATH'
print_path_prepend_shims
echo 'end'
;;
* )
echo 'if [[ ":$PATH:" != *'\':"${PYENV_ROOT}"/shims:\''* ]]; then'
print_path_prepend_shims
echo 'fi'
;;
esac
else
case "$shell" in
fish )
echo 'while set pyenv_index (contains -i -- "'"${PYENV_ROOT}/shims"'" $PATH)'
echo 'set -eg PATH[$pyenv_index]; end; set -e pyenv_index'
print_path_prepend_shims
;;
* )
# Some distros (notably Debian-based) set Bash's SSH_SOURCE_BASHRC compilation option
# that makes it source `bashrc` under SSH even when not interactive.
# This is inhibited by a guard in Debian's stock `bashrc` but some people remove it
# in order to get proper environment for noninteractive remote commands
# (SSH provides /etc/ssh/sshrc and ~/.ssh/rc for that but no-one seems to use them for some reason).
# This has caused an infinite `bashrc` execution loop for those people in the below nested Bash invocation (#2367).
# --norc negates this behavior of such a customized Bash.
echo 'PATH="$(bash --norc -ec '\''IFS=:; paths=($PATH); '
echo 'for i in ${!paths[@]}; do '
echo 'if [[ ${paths[i]} == "'\'\'"${PYENV_ROOT}/shims"\'\''" ]]; then unset '\'\\\'\''paths[i]'\'\\\'\''; '
echo 'fi; done; '
echo 'echo "${paths[*]}"'\'')"'
print_path_prepend_shims
;;
esac
fi
}
function print_path_prepend_shims() {
case "$shell" in
fish )
echo 'set -gx PATH '\'"${PYENV_ROOT}/shims"\'' $PATH'
;;
* )
echo 'export PATH="'"${PYENV_ROOT}"'/shims:${PATH}"'
;;
esac
}
function print_env() {

80
libexec/pyenv-latest Executable file
View File

@@ -0,0 +1,80 @@
#!/usr/bin/env bash
# Summary: Print the latest installed or known version with the given prefix
# Usage: pyenv latest [-k|--known] [-q|--quiet] <prefix>
#
# -k/--known Select from all known versions instead of installed
# -q/--quiet Do not print an error message on resolution failure
set -e
[ -n "$PYENV_DEBUG" ] && set -x
while [[ $# -gt 0 ]]
do
case "$1" in
-k|--known)
FROM_KNOWN=1
shift
;;
-q|--quiet)
QUIET=1
shift
;;
*)
break
;;
esac
done
prefix=$1
exitcode=0
IFS=$'\n'
if [[ -z $FROM_KNOWN ]]; then
DEFINITION_CANDIDATES=( $(pyenv-versions --bare) )
else
DEFINITION_CANDIDATES=( $(python-build --definitions ) )
fi
if printf '%s\n' "${DEFINITION_CANDIDATES[@]}" | grep -qxFe "$prefix"; then
echo "$prefix"
exit $exitcode;
fi
# https://stackoverflow.com/questions/11856054/is-there-an-easy-way-to-pass-a-raw-string-to-grep/63483807#63483807
prefix_re="$(sed 's/[^\^]/[&]/g;s/[\^]/\\&/g' <<< "$prefix")"
# FIXME: more reliable and readable would probably be to loop over them and transform in pure Bash
DEFINITION_CANDIDATES=(\
$(printf '%s\n' "${DEFINITION_CANDIDATES[@]}" | \
grep -Ee "^$prefix_re[-.]" || true))
DEFINITION_CANDIDATES=(\
$(printf '%s\n' "${DEFINITION_CANDIDATES[@]}" | \
sed -E -e '/-dev$/d' -e '/-src$/d' -e '/-latest$/d' -e '/(b|rc)[0-9]+$/d'));
# Compose a sorting key, followed by | and original value
DEFINITION_CANDIDATES=(\
$(printf '%s\n' "${DEFINITION_CANDIDATES[@]}" | \
awk \
'{ if (match($0,"^[[:alnum:]]+-"))
{ print substr($0,0,RLENGTH-1) "." substr($0,RLENGTH+1) "..|" $0; }
else
{ print $0 "...|" $0; }
}'))
DEFINITION_CANDIDATES=(\
$(printf '%s\n' "${DEFINITION_CANDIDATES[@]}" \
| sort -t. -k1,1r -k 2,2nr -k 3,3nr -k4,4nr \
| cut -f2 -d $'|' \
|| true))
DEFINITION="${DEFINITION_CANDIDATES[0]}"
if [[ -n "$DEFINITION" ]]; then
echo "$DEFINITION"
else
if [[ -z $QUIET ]]; then
echo "pyenv: no $([[ -z $FROM_KNOWN ]] && echo installed || echo known) versions match the prefix \`$prefix'" >&2
fi
exitcode=1
fi
exit $exitcode

View File

@@ -42,6 +42,7 @@ OLDIFS="$IFS"
exit 1
fi
else
version="$(pyenv-latest -q "$version" || echo "$version")"
PYENV_PREFIX_PATH="${PYENV_ROOT}/versions/${version}"
fi
if [ -d "$PYENV_PREFIX_PATH" ]; then

View File

@@ -5,18 +5,33 @@ set -e
VERSION_FILE="$1"
function is_version_safe() {
# As needed, check that the constructed path exists as a child path of PYENV_ROOT/versions
version="$1"
if [[ "$version" == ".." || "$version" == */* ]]; then
# Sanity check the value of version to prevent malicious path-traversal
(
cd "$PYENV_ROOT/versions/$version" &>/dev/null || exit 1
[[ "$PWD" == "$PYENV_ROOT/versions/"* ]]
)
return $?
else
return 0
fi
}
if [ -s "$VERSION_FILE" ]; then
# Read the first non-whitespace word from the specified version file.
# Be careful not to load it whole in case there's something crazy in it.
IFS="${IFS}"$'\r'
IFS="$IFS"$'\r'
sep=
while read -n 1024 -r version _ || [[ $version ]]; do
if [[ -z $version || $version == \#* ]]; then
if [[ -z "$version" || "$version" == \#* ]]; then
# Skip empty lines and comments
continue
elif [ "$version" = ".." ] || [[ $version == */* ]]; then
# The version string is used to construct a path and we skip dubious values.
# This prevents issues such as path traversal (CVE-2022-35861).
elif ! is_version_safe "$version"; then
# CVE-2022-35861 allowed arbitrary code execution in some contexts and is mitigated by is_version_safe.
echo "pyenv: invalid version \`$version' ignored in \`$VERSION_FILE'" >&2
continue
fi
printf "%s%s" "$sep" "$version"

View File

@@ -34,6 +34,8 @@ OLDIFS="$IFS"
versions=("${versions[@]}" "${version}")
elif version_exists "${version#python-}"; then
versions=("${versions[@]}" "${version#python-}")
elif resolved_version="$(pyenv-latest -q "$version")"; then
versions=("${versions[@]}" "${resolved_version}")
else
echo "pyenv: version \`$version' is not installed (set by $(pyenv-version-origin))" >&2
any_not_installed=1

View File

@@ -106,7 +106,7 @@ Set or show the shell\-specific Python version
List existing pyenv shims
.TP
.B uninstall
Uninstall a specific Python version
Uninstall Python versions
.TP
.B version
Show the current Python version(s) and its origin
@@ -452,10 +452,10 @@ $ pyenv versions
.fi
.IP "" 0
.SS "pyenv uninstall"
Uninstall a specific Python version\.
Uninstall Python versions\.
.IP "" 4
.nf
Usage: pyenv uninstall [\-f|\-\-force] <version>
Usage: pyenv uninstall [\-f|\-\-force] <version> ...
\-f Attempt to remove the specified version without prompting
for confirmation\. If the version does not exist, do not

View File

@@ -113,6 +113,7 @@ You can set certain environment variables to control the build process.
checksum of the file to the mirror URL.
* `PYTHON_BUILD_SKIP_MIRROR`, if set, forces python-build to download packages from
their original source URLs instead of using a mirror.
* `PYTHON_BUILD_SKIP_HOMEBREW`, if set, will not search for libraries installed by Homebrew on macOS.
* `PYTHON_BUILD_ROOT` overrides the default location from where build definitions
in `share/python-build/` are looked up.
* `PYTHON_BUILD_DEFINITIONS` can be a list of colon-separated paths that get
@@ -231,7 +232,7 @@ the full build log for build failures.
### Testing new python versions
If you are contributing a new python version for python-build,
If you are contributing a new python version for python-build,
you can test the build in a [docker](https://www.docker.com/) container based on Ubuntu 18.04.
With docker installed:
@@ -249,7 +250,7 @@ docker run -it my_container
```
The container will need to be rebuilt whenever you change the repo,
but after the first build, this will be very fast,
but after the first build, this will be very fast,
as the layer including the build dependencies will be cached.
Changes made inside the container will not be persisted.

View File

@@ -145,6 +145,10 @@ IFS=$'\n' scripts=(`pyenv-hooks install`)
IFS="$OLDIFS"
for script in "${scripts[@]}"; do source "$script"; done
# Try to resolve a prefix if user indeed gave a prefix.
# We install the version under the resolved name
# and hooks also see the resolved name
DEFINITION="$(pyenv-latest -q -k "$DEFINITION" || echo "$DEFINITION")"
# Set VERSION_NAME from $DEFINITION, if it is not already set. Then
# compute the installation prefix.

View File

@@ -1,8 +1,8 @@
#!/usr/bin/env bash
#
# Summary: Uninstall a specific Python version
# Summary: Uninstall Python versions
#
# Usage: pyenv uninstall [-f|--force] <version>
# Usage: pyenv uninstall [-f|--force] <version> ...
#
# -f Attempt to remove the specified version without prompting
# for confirmation. If the version does not exist, do not
@@ -33,14 +33,17 @@ if [ "$1" = "-f" ] || [ "$1" = "--force" ]; then
shift
fi
[ "$#" -eq 1 ] || usage 1 >&2
[ "$#" -gt 0 ] || usage 1 >&2
DEFINITION="$1"
case "$DEFINITION" in
"" | -* )
usage 1 >&2
;;
esac
versions=("$@")
for version in "${versions[@]}"; do
case "$version" in
"" | -* )
usage 1 >&2
;;
esac
done
declare -a before_hooks after_hooks
@@ -59,29 +62,36 @@ IFS=$'\n' scripts=(`pyenv-hooks uninstall`)
IFS="$OLDIFS"
for script in "${scripts[@]}"; do source "$script"; done
uninstall-python() {
local DEFINITION="$1"
VERSION_NAME="${DEFINITION##*/}"
PREFIX="${PYENV_ROOT}/versions/${VERSION_NAME}"
local VERSION_NAME="${DEFINITION##*/}"
local PREFIX="${PYENV_ROOT}/versions/${VERSION_NAME}"
if [ -z "$FORCE" ]; then
if [ ! -d "$PREFIX" ]; then
echo "pyenv: version \`$VERSION_NAME' not installed" >&2
exit 1
if [ -z "$FORCE" ]; then
if [ ! -d "$PREFIX" ]; then
echo "pyenv: version \`$VERSION_NAME' not installed" >&2
exit 1
fi
read -p "pyenv: remove $PREFIX? [y|N] "
case "$REPLY" in
y | Y | yes | YES ) ;;
* ) exit 1 ;;
esac
fi
read -p "pyenv: remove $PREFIX? [y|N] "
case "$REPLY" in
y | Y | yes | YES ) ;;
* ) exit 1 ;;
esac
fi
for hook in "${before_hooks[@]}"; do eval "$hook"; done
for hook in "${before_hooks[@]}"; do eval "$hook"; done
if [ -d "$PREFIX" ]; then
rm -rf "$PREFIX"
pyenv-rehash
echo "pyenv: $VERSION_NAME uninstalled"
fi
if [ -d "$PREFIX" ]; then
rm -rf "$PREFIX"
pyenv-rehash
echo "pyenv: $VERSION_NAME uninstalled"
fi
for hook in "${after_hooks[@]}"; do eval "$hook"; done
}
for hook in "${after_hooks[@]}"; do eval "$hook"; done
for version in "${versions[@]}"; do
uninstall-python "$version"
done

View File

@@ -112,6 +112,11 @@ is_mac() {
[ $# -eq 0 ] || [ "$(osx_version)" "$@" ]
}
can_use_homebrew() {
[ -z "$PYTHON_BUILD_SKIP_HOMEBREW" ] || return 1
is_mac || return 1
}
# 9.1 -> 901
# 10.9 -> 1009
# 10.10 -> 1010
@@ -355,12 +360,38 @@ http_head_aria2c() {
}
http_get_aria2c() {
local out="${2:-$(mktemp "out.XXXXXX")}"
if aria2c --allow-overwrite=true --no-conf=true -o "${out}" ${ARIA2_OPTS} "$1" >&4; then
# aria2c always treats -o argument as a relative path
local out dir_out;
if [[ -n "$2" ]]; then
out="$(basename $2)";
dir_out="$(dirname $2)";
else
out="$(mktemp "out.XXXXXX")";
dir_out="$TMPDIR";
fi
# In Ubuntu, aria2c is only available as a snap. Snaps cannot read or write /tmp
# (files cannot be found, any write result is silently discarded).
local aria2c_is_snap;
if [[ $(command -v aria2c) == "/snap/"* ]]; then aria2c_is_snap=1; fi
if [[ -n $aria2c_is_snap ]]; then
local real_dir_out="$dir_out"
# presumably, snaps can always write to under $HOME
dir_out="$HOME"
fi
if aria2c --allow-overwrite=true --no-conf=true -d "${dir_out}" -o "${out}" ${ARIA2_OPTS} "$1" >&4; then
[ -n "$2" ] || cat "${out}"
else
false
fi
ret=$?
if [[ -n "$2" && -n $aria2c_is_snap ]]; then
mv "$dir_out/$out" "$real_dir_out/$out"
fi
return "$ret"
}
http_head_curl() {
@@ -709,7 +740,7 @@ build_package() {
echo "Installing ${package_name}..." >&2
[ -n "$HAS_PATCH" ] && apply_python_patch "$package_name"
[ -n "$HAS_PATCH" ] && apply_patch "$package_name" <(cat "${package_name}.patch")
for command in $commands; do
"build_package_${command}" "$package_name"
@@ -774,6 +805,7 @@ build_package_standard_build() {
else
use_homebrew_zlib || true
fi
use_dsymutil || true
fi
( if [ "${CFLAGS+defined}" ] || [ "${!PACKAGE_CFLAGS+defined}" ]; then
@@ -899,7 +931,7 @@ build_package_micropython() {
"$MAKE" $MAKE_OPTS
cd ../ports/unix
"$MAKE" $MAKE_OPTS axtls
"$MAKE" $MAKE_OPTS CFLAGS_EXTRA="-DMICROPY_PY_SYS_PATH_DEFAULT='\"${PREFIX_PATH}/lib/micropython\"' $CFLAGS_EXTRA"
"$MAKE" $MAKE_OPTS CFLAGS_EXTRA="-DMICROPY_PY_SYS_PATH_DEFAULT='\".frozen:${PREFIX_PATH}/lib/micropython\"' $CFLAGS_EXTRA"
"$MAKE" install $MAKE_INSTALL_OPTS PREFIX="${PREFIX_PATH}"
ln -fs micropython "${PREFIX_PATH}/bin/python"
mkdir -p "${PREFIX_PATH}/lib/micropython"
@@ -932,10 +964,30 @@ pypy_architecture() {
esac
}
graalpy_architecture() {
case "$(uname -s)" in
"Darwin" )
case "$(uname -m)" in
"x86_64" ) echo "macos-amd64" ;;
"arm64" ) echo "macos-aarch64" ;;
* ) return 1 ;;
esac
;;
"Linux" )
case "$(uname -m)" in
"x86_64" ) echo "linux-amd64" ;;
"aarch64" ) echo "linux-aarch64" ;;
* ) return 1 ;;
esac
;;
esac
}
pyston_architecture() {
pypy_architecture
}
# Note: not used by graalpy >= 23.3.0 anymore
build_package_graalpython() {
build_package_copy
ln -fs "${PREFIX_PATH}/bin/graalpython" "${PREFIX_PATH}/bin/python"
@@ -1065,13 +1117,13 @@ setup_builtin_patches() {
local package_name="$1"
local package_patch_path="${DEFINITION_PATH%/*}/patches/${DEFINITION_PATH##*/}/${package_name}"
ORIG_HAS_PATCH="$HAS_PATCH"
# Apply built-in patches if patch was not given from stdin
if [ -z "$HAS_PATCH" ] && [ -d "${package_patch_path}" ]; then
if [[ -n "$HAS_STDIN_PATCH" ]] && package_is_python "${package_name}"; then
cat >"${package_name}.patch"
HAS_PATCH=true
elif [[ -d "${package_patch_path}" ]]; then
{ find "${package_patch_path}" -maxdepth 1 -type f
} 2>/dev/null | sort | xargs cat 1>"${package_name}.patch"
exec <&-
exec <"${package_name}.patch"
HAS_PATCH=true
fi
}
@@ -1079,7 +1131,7 @@ setup_builtin_patches() {
cleanup_builtin_patches() {
local package_name="$1"
rm -f "${package_name}.patch"
HAS_PATCH="$ORIG_HAS_PATCH"
unset HAS_PATCH
}
fix_directory_permissions() {
@@ -1322,10 +1374,10 @@ configured_with_package_dir() {
}
use_homebrew() {
is_mac || return 1
can_use_homebrew || return 1
# unless Homebrew is at the default /usr/local, need to add its paths to
# compiler search to be able to use non-keg-only deps from there
if is_mac && command -v brew &>/dev/null; then
if command -v brew &>/dev/null; then
local brew_prefix="$(brew --prefix 2>/dev/null || true)"
# /usr/local/lib:/usr/lib is the default library search path
if [[ -n $brew_prefix && $brew_prefix != "/usr" && $brew_prefix != "/usr/local" ]]; then
@@ -1344,7 +1396,7 @@ needs_yaml() {
}
use_homebrew_yaml() {
is_mac || return 1
can_use_homebrew || return 1
local libdir="$(brew --prefix libyaml 2>/dev/null || true)"
if [ -d "$libdir" ]; then
echo "python-build: use libyaml from homebrew"
@@ -1388,7 +1440,7 @@ has_broken_mac_readline() {
}
use_homebrew_readline() {
is_mac || return 1
can_use_homebrew || return 1
if ! configured_with_package_dir "python" "readline/rlconf.h"; then
local libdir="$(brew --prefix readline 2>/dev/null || true)"
if [ -d "$libdir" ]; then
@@ -1429,7 +1481,7 @@ has_broken_mac_openssl() {
}
use_homebrew_openssl() {
is_mac || return 1
can_use_homebrew || return 1
command -v brew >/dev/null || return 1
for openssl in ${PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA:-openssl}; do
local ssldir="$(brew --prefix "${openssl}" || true)"
@@ -1529,7 +1581,7 @@ build_package_verify_openssl() {
}
use_homebrew_zlib() {
is_mac || return 1
can_use_homebrew || return 1
local brew_zlib="$(brew --prefix zlib 2>/dev/null || true)"
if [ -d "$brew_zlib" ]; then
echo "python-build: use zlib from homebrew"
@@ -1538,6 +1590,8 @@ use_homebrew_zlib() {
}
use_xcode_sdk_zlib() {
# If a custom compiler is used, including XCode SDK will likely break it
[[ "${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)"
if [ -d "$xc_sdk_path" ]; then
echo "python-build: use zlib from xcode sdk"
@@ -1549,14 +1603,17 @@ use_xcode_sdk_zlib() {
}
use_homebrew_tcltk() {
is_mac || return 1
can_use_homebrew || return 1
# get the version from the folder that homebrew versions
local tcltk_libdir="$(brew --prefix tcl-tk 2>/dev/null || true)"
if [ -d "$tcltk_libdir" ]; then
echo "python-build: use tcl-tk from homebrew"
local tcltk_version="$(sh -c '. '"$tcltk_libdir"'/lib/tclConfig.sh; echo $TCL_VERSION')"
package_option python configure --with-tcltk-libs="-L$tcltk_libdir/lib -ltcl$tcltk_version -ltk$tcltk_version"
package_option python configure --with-tcltk-includes="-I$tcltk_libdir/include"
if [[ -z "$PYTHON_BUILD_TCLTK_USE_PKGCONFIG" ]]; then
local tcltk_version="$(sh -c '. '"$tcltk_libdir"'/lib/tclConfig.sh; echo $TCL_VERSION')"
package_option python configure --with-tcltk-libs="-L$tcltk_libdir/lib -ltcl$tcltk_version -ltk$tcltk_version"
package_option python configure --with-tcltk-includes="-I$tcltk_libdir/include"
fi
export PKG_CONFIG_PATH="${tcltk_libdir}/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}"
fi
}
@@ -1591,13 +1648,13 @@ use_custom_tcltk() {
get_tcltk_flag_from() {
IFS=$'\n'
# parse input string into array
local opts_arr=( $(xargs -n1 <<<"$1") )
local opts_arr=( $(xargs -n1 <<<"$1") )
# iterate through `opts_arr`, break if `--with-tcltk-libs=` was found.
for opts in ${opts_arr[@]}; do
# `--with-tcltk-libs=` must be the prefix.
if [[ "$opts" == "--with-tcltk-libs="* ]]; then
# return
# return
echo "$opts"
break
fi
@@ -1607,7 +1664,7 @@ get_tcltk_flag_from() {
}
use_tcltk() {
if is_mac; then
if can_use_homebrew; then
local tcltk_libdir="$(brew --prefix tcl-tk 2>/dev/null || true)"
fi
local tcl_tk_libs="$(get_tcltk_flag_from "$PYTHON_CONFIGURE_OPTS")"
@@ -1621,6 +1678,16 @@ use_tcltk() {
fi
}
# Since 3.12, CPython can add DWARF debug information in MacOS
# using Apple's nonstandard way, `dsymutil', that creates a "dSYM bundle"
# that's supposed to be installed alongside executables
# (https://github.com/python/cpython/issues/95973).
use_dsymutil() {
if [[ -n "$PYTHON_BUILD_CONFIGURE_WITH_DSYMUTIL" ]] && is_mac; then
package_option python configure --with-dsymutil
fi
}
build_package_enable_shared() {
package_option python configure --enable-shared
}
@@ -1637,31 +1704,33 @@ build_package_auto_tcltk() {
fi
}
# extglob must be set at parse time, not at runtime
# extglob must be set at both parse time and runtime
# https://stackoverflow.com/questions/49283740/bash-script-throws-syntax-errors-when-the-extglob-option-is-set-inside-a-subsh
#
# The function is *parsed* with "extglob" only if an outer `shopt -s exglob`
# exists; at *runtime* you still need to activate it *within* the function.
#
shopt -s extglob
apply_python_patch() {
local patchfile
# needed at runtime
package_is_python() {
shopt -s extglob
case "$1" in
Python-* | jython-* | pypy-* | pypy[0-9].+([0-9])-* | stackless-* )
patchfile="$(mktemp "${TMP}/python-patch.XXXXXX")"
cat "${2:--}" >"$patchfile"
local striplevel=0
grep -q '^diff --git a/' "$patchfile" && striplevel=1
patch -p$striplevel --force -i "$patchfile"
;;
Python-* | jython-* | pypy-* | pypy[0-9].+([0-9])-* | stackless-* )
return 0
;;
esac
return 1
shopt -u extglob
}
shopt -u extglob
apply_patch() {
local package_name="$1"
local patchfile
patchfile="$(mktemp "${TMP}/python-patch.XXXXXX")"
cat "${2:--}" >"$patchfile"
local striplevel=0
grep -q '^diff --git a/' "$patchfile" && striplevel=1
patch -p$striplevel --force -i "$patchfile"
}
build_package_symlink_version_suffix() {
if [[ "$CONFIGURE_OPTS $PYTHON_CONFIGURE_OPTS" == *"--enable-framework"* ]]; then
if [ -e "${PREFIX_PATH}/bin" ]; then
@@ -2000,7 +2069,7 @@ for option in "${OPTIONS[@]}"; do
VERBOSE=true
;;
"p" | "patch" )
HAS_PATCH=true
HAS_STDIN_PATCH=true
;;
"g" | "debug" )
DEBUG=true

View File

@@ -0,0 +1,9 @@
prefer_openssl11
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 "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.7" "https://www.python.org/ftp/python/3.10.7/Python-3.10.7.tar.xz#6eed8415b7516fb2f260906db5d48dd4c06acc0cb24a7d6cc15296a604dcdc48" standard verify_py310 copy_python_gdb ensurepip
else
install_package "Python-3.10.7" "https://www.python.org/ftp/python/3.10.7/Python-3.10.7.tgz#1b2e4e2df697c52d36731666979e648beeda5941d0f95740aafbf4163e5cc126" standard verify_py310 copy_python_gdb ensurepip
fi

View File

@@ -0,0 +1,9 @@
prefer_openssl11
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 "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.8" "https://www.python.org/ftp/python/3.10.8/Python-3.10.8.tar.xz#6a30ecde59c47048013eb5a658c9b5dec277203d2793667f578df7671f7f03f3" standard verify_py310 copy_python_gdb ensurepip
else
install_package "Python-3.10.8" "https://www.python.org/ftp/python/3.10.8/Python-3.10.8.tgz#f400c3fb394b8bef1292f6dc1292c5fadc3533039a5bc0c3e885f3e16738029a" standard verify_py310 copy_python_gdb ensurepip
fi

View File

@@ -0,0 +1,9 @@
prefer_openssl11
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 "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.9" "https://www.python.org/ftp/python/3.10.9/Python-3.10.9.tar.xz#5ae03e308260164baba39921fdb4dbf8e6d03d8235a939d4582b33f0b5e46a83" standard verify_py310 copy_python_gdb ensurepip
else
install_package "Python-3.10.9" "https://www.python.org/ftp/python/3.10.9/Python-3.10.9.tgz#4ccd7e46c8898f4c7862910a1703aa0e63525913a519abb2f55e26220a914d88" standard verify_py310 copy_python_gdb ensurepip
fi

View File

@@ -1,5 +1,6 @@
prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=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 "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.11-dev" "https://github.com/python/cpython" 3.11 standard verify_py311 copy_python_gdb ensurepip

View File

@@ -0,0 +1,10 @@
prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=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 "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.0" "https://www.python.org/ftp/python/3.11.0/Python-3.11.0.tar.xz#a57dc82d77358617ba65b9841cee1e3b441f386c3789ddc0676eca077f2951c3" standard verify_py311 copy_python_gdb ensurepip
else
install_package "Python-3.11.0" "https://www.python.org/ftp/python/3.11.0/Python-3.11.0.tgz#64424e96e2457abbac899b90f9530985b51eef2905951febd935f0e73414caeb" standard verify_py311 copy_python_gdb ensurepip
fi

View File

@@ -1,9 +0,0 @@
prefer_openssl11
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 "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then
install_package "Python-3.11.0b5" "https://www.python.org/ftp/python/3.11.0/Python-3.11.0b5.tar.xz#3810bd22f7dc34a99c2a2eb4b85264a4df4f05ef59c4e0ccc2ea82ee9c491698" standard verify_py311 copy_python_gdb ensurepip
else
install_package "Python-3.11.0b5" "https://www.python.org/ftp/python/3.11.0/Python-3.11.0b5.tgz#3f7d1a4ab0e64425f4ffd92d49de192ad2ee1c62bc52e3877e9f7b254c702e60" standard verify_py311 copy_python_gdb ensurepip
fi

View File

@@ -0,0 +1,10 @@
prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=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 "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.1" "https://www.python.org/ftp/python/3.11.1/Python-3.11.1.tar.xz#85879192f2cffd56cb16c092905949ebf3e5e394b7f764723529637901dfb58f" standard verify_py311 copy_python_gdb ensurepip
else
install_package "Python-3.11.1" "https://www.python.org/ftp/python/3.11.1/Python-3.11.1.tgz#baed518e26b337d4d8105679caf68c5c32630d702614fc174e98cb95c46bdfa4" standard verify_py311 copy_python_gdb ensurepip
fi

View File

@@ -1,5 +1,7 @@
prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
export PYTHON_BUILD_CONFIGURE_WITH_DSYMUTIL=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 "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.12-dev" "https://github.com/python/cpython" main standard verify_py312 copy_python_gdb ensurepip

View File

@@ -0,0 +1,9 @@
prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=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 "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.0a3" "https://www.python.org/ftp/python/3.12.0/Python-3.12.0a3.tar.xz#1b64b3075e0a9241974e580e09b09c9117a1c4e2be698039201ef1d8a73453d1" standard verify_py312 copy_python_gdb ensurepip
else
install_package "Python-3.12.0a3" "https://www.python.org/ftp/python/3.12.0/Python-3.12.0a3.tgz#fd414e6b6520171f5cefc5cba1067265187a322417f7bdec8d024db7fc8fbe96" standard verify_py312 copy_python_gdb ensurepip
fi

View File

@@ -0,0 +1,9 @@
prefer_openssl11
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 "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.7.14" "https://www.python.org/ftp/python/3.7.14/Python-3.7.14.tar.xz#4157ae31eb81af19e81c36882610491b0fb8f50e00fa8a17b095c88908b9c45c" standard verify_py37 copy_python_gdb ensurepip
else
install_package "Python-3.7.14" "https://www.python.org/ftp/python/3.7.14/Python-3.7.14.tgz#82b2abf8978caa61a9011d166eede831b32de9cbebc0db8162900fa23437b709" standard verify_py37 copy_python_gdb ensurepip
fi

View File

@@ -0,0 +1,9 @@
prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=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 "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.7.15" "https://www.python.org/ftp/python/3.7.15/Python-3.7.15.tar.xz#5911475a07ac2b53d746e88a0716af6d2b4734941919136ea0d33fb9c75b9714" standard verify_py37 copy_python_gdb ensurepip
else
install_package "Python-3.7.15" "https://www.python.org/ftp/python/3.7.15/Python-3.7.15.tgz#cf2993798ae8430f3af3a00d96d9fdf320719f4042f039380dca79967c25e436" standard verify_py37 copy_python_gdb ensurepip
fi

View File

@@ -0,0 +1,9 @@
prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=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 "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.7.16" "https://www.python.org/ftp/python/3.7.16/Python-3.7.16.tar.xz#8338f0c2222d847e904c955369155dc1beeeed806e8d5ef04b00ef4787238bfd" standard verify_py37 copy_python_gdb ensurepip
else
install_package "Python-3.7.16" "https://www.python.org/ftp/python/3.7.16/Python-3.7.16.tgz#0cf2da07fa464636755215415909e22eb1d058817af4824bc15af8390d05fb38" standard verify_py37 copy_python_gdb ensurepip
fi

View File

@@ -0,0 +1,9 @@
prefer_openssl11
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 "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.8.14" "https://www.python.org/ftp/python/3.8.14/Python-3.8.14.tar.xz#5d77e278271ba803e9909a41a4f3baca006181c93ada682a5e5fe8dc4a24c5f3" standard verify_py38 copy_python_gdb ensurepip
else
install_package "Python-3.8.14" "https://www.python.org/ftp/python/3.8.14/Python-3.8.14.tgz#41f959c480c59211feb55d5a28851a56c7e22d02ef91035606ebb21011723c31" standard verify_py38 copy_python_gdb ensurepip
fi

View File

@@ -0,0 +1,9 @@
prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=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 "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.8.15" "https://www.python.org/ftp/python/3.8.15/Python-3.8.15.tar.xz#5114fc7918a2a5e20eb5aac696b30c36f412c6ef24b13f5c9eb9e056982d9550" standard verify_py38 copy_python_gdb ensurepip
else
install_package "Python-3.8.15" "https://www.python.org/ftp/python/3.8.15/Python-3.8.15.tgz#924d46999df82aa2eaa1de5ca51d6800ffb56b4bf52486a28f40634e3362abc4" standard verify_py38 copy_python_gdb ensurepip
fi

View File

@@ -0,0 +1,9 @@
prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=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 "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.8.16" "https://www.python.org/ftp/python/3.8.16/Python-3.8.16.tar.xz#d85dbb3774132473d8081dcb158f34a10ccad7a90b96c7e50ea4bb61f5ce4562" standard verify_py38 copy_python_gdb ensurepip
else
install_package "Python-3.8.16" "https://www.python.org/ftp/python/3.8.16/Python-3.8.16.tgz#71ca9d935637ed2feb59e90a368361dc91eca472a90acb1d344a2e8178ccaf10" standard verify_py38 copy_python_gdb ensurepip
fi

View File

@@ -0,0 +1,9 @@
prefer_openssl11
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 "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.9.14" "https://www.python.org/ftp/python/3.9.14/Python-3.9.14.tar.xz#651304d216c8203fe0adf1a80af472d8e92c3b0e0a7892222ae4d9f3ae4debcf" standard verify_py39 copy_python_gdb ensurepip
else
install_package "Python-3.9.14" "https://www.python.org/ftp/python/3.9.14/Python-3.9.14.tgz#9201836e2c16361b2b7408680502393737d44f227333fe2e5729c7d5f6041675" standard verify_py39 copy_python_gdb ensurepip
fi

View File

@@ -0,0 +1,9 @@
prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=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 "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.9.15" "https://www.python.org/ftp/python/3.9.15/Python-3.9.15.tar.xz#12daff6809528d9f6154216950423c9e30f0e47336cb57c6aa0b4387dd5eb4b2" standard verify_py39 copy_python_gdb ensurepip
else
install_package "Python-3.9.15" "https://www.python.org/ftp/python/3.9.15/Python-3.9.15.tgz#48d1ccb29d5fbaf1fb8f912271d09f7450e426d4dfe95978ef6aaada70ece4d8" standard verify_py39 copy_python_gdb ensurepip
fi

View File

@@ -0,0 +1,9 @@
prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=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 "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.9.16" "https://www.python.org/ftp/python/3.9.16/Python-3.9.16.tar.xz#22dddc099246dd2760665561e8adb7394ea0cc43a72684c6480f9380f7786439" standard verify_py39 copy_python_gdb ensurepip
else
install_package "Python-3.9.16" "https://www.python.org/ftp/python/3.9.16/Python-3.9.16.tgz#1ad539e9dbd2b42df714b69726e0693bc6b9d2d2c8e91c2e43204026605140c5" standard verify_py39 copy_python_gdb ensurepip
fi

View File

@@ -0,0 +1,31 @@
require_distro Fedora 32 &>/dev/null || \
{ echo
colorize 1 "WARNING"
cat >&2 <<!
: The Cinder compiler only officially supports
Facebook's Docker images which are Fedora 32 - based.
It may fail to build on a system
with a different GCC and/or Glibc version.
!
echo
}
[[ $(${CC:-gcc} -dumpversion 2>/dev/null) == 10 ]] || \
{ command -v "gcc-10" >/dev/null && \
export CC="gcc-10" && \
echo "python-build: setting the compiler to \`gcc-10'"; } || \
{
echo
colorize 1 WARNING
cat >&2 <<!
: GCC 10 is not found on PATH.
The build may fail.
!
echo
}
prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=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 "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline
install_git "Cinder-3.8-dev" "https://github.com/facebookincubator/cinder" "cinder/3.8" standard verify_py38 copy_python_gdb ensurepip

View File

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

View File

@@ -0,0 +1,4 @@
has_tar_xz_support \
&& { install=install_package; src="https://micropython.org/resources/source/micropython-1.18.tar.xz#96fc71b42ed331c64e1adc5a830ec4f29f2975c23e8751109c03f32b80fa3eb4"; } \
|| { install=install_zip; src="https://micropython.org/resources/source/micropython-1.18.zip#90fa8049cf275310638b9e9c77121f6042f7250b814ef622f9522befde009f57"; }
$install micropython-1.18 "$src" micropython

View File

@@ -0,0 +1,4 @@
has_tar_xz_support \
&& { install=install_package; src="https://micropython.org/resources/source/micropython-1.19.1.tar.xz#940e3815e8c425c6eaed3a2aa30d320220cc012a2654b6e086e1b6f0567df350"; } \
|| { install=install_zip; src="https://micropython.org/resources/source/micropython-1.19.1.zip#7047ce208627457c6881850527edb78189a1855a974aa34e2d929c9a3b3c5cc3"; }
$install micropython-1.19.1 "$src" micropython

View File

@@ -12,7 +12,7 @@ case "$(anaconda_architecture 2>/dev/null || true)" in
install_script "Miniconda3-py39_4.12.0-Linux-x86_64" "https://repo.anaconda.com/miniconda/Miniconda3-py39_4.12.0-Linux-x86_64.sh#7843dd7d0a2c53b0df37ca8189672992" "miniconda" verify_py39
;;
"MacOSX-arm64" )
install_script "Miniconda3-py39_4.12.0-MacOSX-arm64" "https://repo.anaconda.com/miniconda/Miniconda3-py39_4.12.0-MacOSX-arm64.sh#31251793539cf952ee99c18e34c30c7f" "miniconda" verify_py39
install_script "Miniconda3-py39_4.12.0-MacOSX-arm64" "https://repo.anaconda.com/miniconda/Miniconda3-py39_4.12.0-MacOSX-arm64.sh#f7448cfeb278f2a84ed903db02d5525c" "miniconda" verify_py39
;;
"MacOSX-x86_64" )
install_script "Miniconda3-py39_4.12.0-MacOSX-x86_64" "https://repo.anaconda.com/miniconda/Miniconda3-py39_4.12.0-MacOSX-x86_64.sh#143b9bb03b6e4865be4ebbf40b108772" "miniconda" verify_py39

View File

@@ -0,0 +1,12 @@
diff --git a/test/v3ext.c b/test/v3ext.c
index 7a240cd706..6cec6f1a9b 100644
--- a/test/v3ext.c
+++ b/test/v3ext.c
@@ -15,6 +15,7 @@
#include <openssl/err.h>
#include "internal/nelem.h"
+#include <string.h>
#include "testutil.h"
static const char *infile;

View File

@@ -0,0 +1,310 @@
From: Christian Hammond <christian@beanbaginc.com>
Date: Wed, 15 Dec 2021 23:12:36 -0800
Subject: Port ctypes and system libffi patches for arm64/macOS 10.15+ to Python 3.7.12
This ports the following ctypes and libffi pyenv patches for Python
2.7.18 to Python 3.7.12:
* `0004-Use-system-libffi-for-Mac-OS-10.15-and-up.patch`
* `0005-ctypes-use-the-correct-ABI-for-variadic-functions.patch`
* `0006-ctypes-probe-libffi-for-ffi_closure_alloc-and-ffi_pr.patch`
These patches enable use of system libffi (fixing a broken `ctypes`
module on arm64 targets) and enable calling variadic functions on arm64.
They've been combined from patches port from Homebrew to pyenv by Takumi
Sueda, updated to work on the Python 3.7.12 codebase.
The Homebrew patches are themselves backports of changes in Python 3.9
and 3.10. That patch can be found at:
https://github.com/Homebrew/formula-patches/blob/master/python/3.8.7.patch
diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst
index 715d595b24..7743144978 100644
--- a/Doc/library/ctypes.rst
+++ b/Doc/library/ctypes.rst
@@ -1551,6 +1551,13 @@ They are instances of a private class:
value usable as argument (integer, string, ctypes instance). This allows
defining adapters that can adapt custom objects as function parameters.
+ .. attribute:: variadic
+
+ Assign a boolean to specify that the function takes a variable number of
+ arguments. This does not matter on most platforms, but for Apple arm64
+ platforms variadic functions have a different calling convention than
+ normal functions.
+
.. attribute:: errcheck
Assign a Python function or another callable to this attribute. The
diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py
index 4ebd82d3e0..7b73c190b6 100644
--- a/Lib/test/test_unicode.py
+++ b/Lib/test/test_unicode.py
@@ -2458,11 +2458,14 @@ class CAPITest(unittest.TestCase):
def test_from_format(self):
support.import_module('ctypes')
from ctypes import (
+ c_char_p,
pythonapi, py_object, sizeof,
c_int, c_long, c_longlong, c_ssize_t,
c_uint, c_ulong, c_ulonglong, c_size_t, c_void_p)
name = "PyUnicode_FromFormat"
_PyUnicode_FromFormat = getattr(pythonapi, name)
+ _PyUnicode_FromFormat.argtypes = (c_char_p,)
+ _PyUnicode_FromFormat.variadic = True
_PyUnicode_FromFormat.restype = py_object
def PyUnicode_FromFormat(format, *args):
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
index dd0c61fd8a..79137e1dc7 100644
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -3174,6 +3174,34 @@ PyCFuncPtr_get_restype(PyCFuncPtrObject *self, void *Py_UNUSED(ignored))
}
}
+static int
+PyCFuncPtr_set_variadic(PyCFuncPtrObject *self, PyObject *ob)
+{
+ StgDictObject *dict = PyObject_stgdict((PyObject *)self);
+ assert(dict);
+ int r = PyObject_IsTrue(ob);
+ if (r == 1) {
+ dict->flags |= FUNCFLAG_VARIADIC;
+ return 0;
+ } else if (r == 0) {
+ dict->flags &= ~FUNCFLAG_VARIADIC;
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+static PyObject *
+PyCFuncPtr_get_variadic(PyCFuncPtrObject *self)
+{
+ StgDictObject *dict = PyObject_stgdict((PyObject *)self);
+ assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
+ if (dict->flags & FUNCFLAG_VARIADIC)
+ Py_RETURN_TRUE;
+ else
+ Py_RETURN_FALSE;
+}
+
static int
PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored))
{
@@ -3219,6 +3247,8 @@ static PyGetSetDef PyCFuncPtr_getsets[] = {
{ "argtypes", (getter)PyCFuncPtr_get_argtypes,
(setter)PyCFuncPtr_set_argtypes,
"specify the argument types", NULL },
+ { "variadic", (getter)PyCFuncPtr_get_variadic, (setter)PyCFuncPtr_set_variadic,
+ "specify if function takes variable number of arguments", NULL },
{ NULL, NULL }
};
@@ -5632,6 +5662,7 @@ PyInit__ctypes(void)
PyModule_AddObject(m, "FUNCFLAG_USE_ERRNO", PyLong_FromLong(FUNCFLAG_USE_ERRNO));
PyModule_AddObject(m, "FUNCFLAG_USE_LASTERROR", PyLong_FromLong(FUNCFLAG_USE_LASTERROR));
PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyLong_FromLong(FUNCFLAG_PYTHONAPI));
+ PyModule_AddObject(m, "FUNCFLAG_VARIADIC", PyLong_FromLong(FUNCFLAG_VARIADIC));
PyModule_AddStringConstant(m, "__version__", "1.1.0");
PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove));
diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c
index 9cbf9801ad..e7fe11176b 100644
--- a/Modules/_ctypes/callproc.c
+++ b/Modules/_ctypes/callproc.c
@@ -754,7 +756,8 @@ static int _call_function_pointer(int flags,
ffi_type **atypes,
ffi_type *restype,
void *resmem,
- int argcount)
+ int argcount,
+ int argtypecount)
{
PyThreadState *_save = NULL; /* For Py_BLOCK_THREADS and Py_UNBLOCK_THREADS */
PyObject *error_object = NULL;
@@ -780,15 +783,39 @@ static int _call_function_pointer(int flags,
if ((flags & FUNCFLAG_CDECL) == 0)
cc = FFI_STDCALL;
#endif
- if (FFI_OK != ffi_prep_cif(&cif,
- cc,
- argcount,
- restype,
- atypes)) {
- PyErr_SetString(PyExc_RuntimeError,
- "ffi_prep_cif failed");
- return -1;
+
+#if HAVE_FFI_PREP_CIF_VAR
+ /* Everyone SHOULD set f.variadic=True on variadic function pointers, but
+ * lots of existing code will not. If there's at least one arg and more
+ * args are passed than are defined in the prototype, then it must be a
+ * variadic function. */
+ if ((flags & FUNCFLAG_VARIADIC) ||
+ (argtypecount != 0 && argcount > argtypecount))
+ {
+ if (FFI_OK != ffi_prep_cif_var(&cif,
+ cc,
+ argtypecount,
+ argcount,
+ restype,
+ atypes)) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "ffi_prep_cif_var failed");
+ return -1;
+ }
+ } else {
+#endif
+ if (FFI_OK != ffi_prep_cif(&cif,
+ cc,
+ argcount,
+ restype,
+ atypes)) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "ffi_prep_cif failed");
+ return -1;
+ }
+#if HAVE_FFI_PREP_CIF_VAR
}
+#endif
if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) {
error_object = _ctypes_get_errobj(&space);
@@ -1187,9 +1214,8 @@ PyObject *_ctypes_callproc(PPROC pProc,
if (-1 == _call_function_pointer(flags, pProc, avalues, atypes,
rtype, resbuf,
- Py_SAFE_DOWNCAST(argcount,
- Py_ssize_t,
- int)))
+ Py_SAFE_DOWNCAST(argcount, Py_ssize_t, int),
+ Py_SAFE_DOWNCAST(argtype_count, Py_ssize_t, int)))
goto cleanup;
#ifdef WORDS_BIGENDIAN
diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h
index e58f85233c..e45975f6ad 100644
--- a/Modules/_ctypes/ctypes.h
+++ b/Modules/_ctypes/ctypes.h
@@ -285,6 +285,7 @@ PyObject *_ctypes_callproc(PPROC pProc,
#define FUNCFLAG_PYTHONAPI 0x4
#define FUNCFLAG_USE_ERRNO 0x8
#define FUNCFLAG_USE_LASTERROR 0x10
+#define FUNCFLAG_VARIADIC 0x20
#define TYPEFLAG_ISPOINTER 0x100
#define TYPEFLAG_HASPOINTER 0x200
diff --git a/setup.py b/setup.py
index bf90600eaa..48ff120e9a 100644
--- a/setup.py
+++ b/setup.py
@@ -142,6 +142,13 @@ def macosx_sdk_root():
return MACOS_SDK_ROOT
+def is_macosx_at_least(vers):
+ if host_platform == 'darwin':
+ dep_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
+ if dep_target:
+ return tuple(map(int, str(dep_target).split('.'))) >= vers
+ return False
+
def is_macosx_sdk_path(path):
"""
Returns True if 'path' can be located in an OSX SDK
@@ -150,6 +157,13 @@ def is_macosx_sdk_path(path):
or path.startswith('/System/')
or path.startswith('/Library/') )
+def grep_headers_for(function, headers):
+ for header in headers:
+ with open(header, 'r') as f:
+ if function in f.read():
+ return True
+ return False
+
def find_file(filename, std_dirs, paths):
"""Searches for the directory where a given file is located,
and returns a possibly-empty list of additional directories, or None
@@ -1972,7 +1986,11 @@ class PyBuildExt(build_ext):
return True
def detect_ctypes(self, inc_dirs, lib_dirs):
- self.use_system_libffi = False
+ if not sysconfig.get_config_var("LIBFFI_INCLUDEDIR") and is_macosx_at_least((10,15)):
+ self.use_system_libffi = True
+ else:
+ self.use_system_libffi = '--with-system-ffi' in sysconfig.get_config_var("CONFIG_ARGS")
+
include_dirs = []
extra_compile_args = []
extra_link_args = []
@@ -2018,30 +2036,47 @@ class PyBuildExt(build_ext):
libraries=['m'])
self.extensions.extend([ext, ext_test])
+ ffi_inc = sysconfig.get_config_var("LIBFFI_INCLUDEDIR")
+ ffi_lib = None
+
if host_platform == 'darwin':
- if '--with-system-ffi' not in sysconfig.get_config_var("CONFIG_ARGS"):
+ if not self.use_system_libffi:
return
- # OS X 10.5 comes with libffi.dylib; the include files are
- # in /usr/include/ffi
- inc_dirs.append('/usr/include/ffi')
-
- ffi_inc = [sysconfig.get_config_var("LIBFFI_INCLUDEDIR")]
- if not ffi_inc or ffi_inc[0] == '':
- ffi_inc = find_file('ffi.h', [], inc_dirs)
- if ffi_inc is not None:
- ffi_h = ffi_inc[0] + '/ffi.h'
+ ffi_in_sdk = os.path.join(macosx_sdk_root(), "usr/include/ffi")
+ if os.path.exists(ffi_in_sdk):
+ ffi_inc = ffi_in_sdk
+ ffi_lib = 'ffi'
+ else:
+ # OS X 10.5 comes with libffi.dylib; the include files are
+ # in /usr/include/ffi
+ inc_dirs.append('/usr/include/ffi')
+
+ if not ffi_inc:
+ found = find_file('ffi.h', [], inc_dirs)
+ if found:
+ ffi_inc = found[0]
+ if ffi_inc:
+ ffi_h = ffi_inc + '/ffi.h'
if not os.path.exists(ffi_h):
ffi_inc = None
print('Header file {} does not exist'.format(ffi_h))
- ffi_lib = None
- if ffi_inc is not None:
- for lib_name in ('ffi', 'ffi_pic'):
+
+ if ffi_lib is None and ffi_inc:
+ for lib_name in ('ffi_convenience', 'ffi_pic', 'ffi'):
if (self.compiler.find_library_file(lib_dirs, lib_name)):
ffi_lib = lib_name
break
if ffi_inc and ffi_lib:
- ext.include_dirs.extend(ffi_inc)
+ ffi_headers = glob(os.path.join(ffi_inc, '*.h'))
+ if grep_headers_for('ffi_closure_alloc', ffi_headers):
+ try:
+ sources.remove('_ctypes/malloc_closure.c')
+ except ValueError:
+ pass
+ if grep_headers_for('ffi_prep_cif_var', ffi_headers):
+ ext.extra_compile_args.append("-DHAVE_FFI_PREP_CIF_VAR=1")
+ ext.include_dirs.append(ffi_inc)
ext.libraries.append(ffi_lib)
self.use_system_libffi = True
--
2.30.1 (Apple Git-130)

View File

@@ -0,0 +1,37 @@
From f2595c038ed7bfd182d9d05d83786106ebd02ca0 Mon Sep 17 00:00:00 2001
From: Lawrence D'Anna <64555057+lawrence-danna-apple@users.noreply.github.com>
Date: Tue, 30 Jun 2020 02:15:46 -0700
Subject: [PATCH] bpo-41100: fix _decimal for arm64 Mac OS (GH-21228)
Patch by Lawrence Danna.
---
.../Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst | 1 +
Modules/_decimal/libmpdec/mpdecimal.h | 3 +++
2 files changed, 4 insertions(+)
create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst
diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst
new file mode 100644
index 0000000000..d6176d69f0
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst
@@ -0,0 +1 @@
+add arm64 to the allowable Mac OS arches in mpdecimal.h
\ No newline at end of file
diff --git a/Modules/_decimal/libmpdec/mpdecimal.h b/Modules/_decimal/libmpdec/mpdecimal.h
index a67dd9bc12..3e9c8185c3 100644
--- a/Modules/_decimal/libmpdec/mpdecimal.h
+++ b/Modules/_decimal/libmpdec/mpdecimal.h
@@ -135,6 +135,9 @@ const char *mpd_version(void);
#elif defined(__x86_64__)
#define CONFIG_64
#define ASM
+ #elif defined(__arm64__)
+ #define CONFIG_64
+ #define ANSI
#else
#error "unknown architecture for universal build."
#endif
--
2.37.3

View File

@@ -0,0 +1,30 @@
From 245427d207ee88a4ba26a66c3de350bcbcc036f2 Mon Sep 17 00:00:00 2001
From: Ronald Oussoren <ronaldoussoren@mac.com>
Date: Sat, 14 Nov 2020 16:07:47 +0100
Subject: [PATCH] bpo-42351: Avoid error when opening header with non-UTF8
encoding (GH-23279)
grep_headers_for() would error out when a header contained
text that cannot be interpreted as UTF-8.
cherry-picked from 7a27c7ed4b by Pedro Fonini <fonini@ip.tv>
---
setup.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/setup.py b/setup.py
index f211989aac..467362813d 100644
--- a/setup.py
+++ b/setup.py
@@ -159,7 +159,7 @@ def is_macosx_sdk_path(path):
def grep_headers_for(function, headers):
for header in headers:
- with open(header, 'r') as f:
+ with open(header, 'r', errors='surrogateescape') as f:
if function in f.read():
return True
return False
--
2.34.1

View File

@@ -0,0 +1,310 @@
From: Christian Hammond <christian@beanbaginc.com>
Date: Wed, 15 Dec 2021 23:12:36 -0800
Subject: Port ctypes and system libffi patches for arm64/macOS 10.15+ to Python 3.7.12
This ports the following ctypes and libffi pyenv patches for Python
2.7.18 to Python 3.7.12:
* `0004-Use-system-libffi-for-Mac-OS-10.15-and-up.patch`
* `0005-ctypes-use-the-correct-ABI-for-variadic-functions.patch`
* `0006-ctypes-probe-libffi-for-ffi_closure_alloc-and-ffi_pr.patch`
These patches enable use of system libffi (fixing a broken `ctypes`
module on arm64 targets) and enable calling variadic functions on arm64.
They've been combined from patches port from Homebrew to pyenv by Takumi
Sueda, updated to work on the Python 3.7.12 codebase.
The Homebrew patches are themselves backports of changes in Python 3.9
and 3.10. That patch can be found at:
https://github.com/Homebrew/formula-patches/blob/master/python/3.8.7.patch
diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst
index 715d595b24..7743144978 100644
--- a/Doc/library/ctypes.rst
+++ b/Doc/library/ctypes.rst
@@ -1551,6 +1551,13 @@ They are instances of a private class:
value usable as argument (integer, string, ctypes instance). This allows
defining adapters that can adapt custom objects as function parameters.
+ .. attribute:: variadic
+
+ Assign a boolean to specify that the function takes a variable number of
+ arguments. This does not matter on most platforms, but for Apple arm64
+ platforms variadic functions have a different calling convention than
+ normal functions.
+
.. attribute:: errcheck
Assign a Python function or another callable to this attribute. The
diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py
index 4ebd82d3e0..7b73c190b6 100644
--- a/Lib/test/test_unicode.py
+++ b/Lib/test/test_unicode.py
@@ -2458,11 +2458,14 @@ class CAPITest(unittest.TestCase):
def test_from_format(self):
support.import_module('ctypes')
from ctypes import (
+ c_char_p,
pythonapi, py_object, sizeof,
c_int, c_long, c_longlong, c_ssize_t,
c_uint, c_ulong, c_ulonglong, c_size_t, c_void_p)
name = "PyUnicode_FromFormat"
_PyUnicode_FromFormat = getattr(pythonapi, name)
+ _PyUnicode_FromFormat.argtypes = (c_char_p,)
+ _PyUnicode_FromFormat.variadic = True
_PyUnicode_FromFormat.restype = py_object
def PyUnicode_FromFormat(format, *args):
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
index dd0c61fd8a..79137e1dc7 100644
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -3174,6 +3174,34 @@ PyCFuncPtr_get_restype(PyCFuncPtrObject *self, void *Py_UNUSED(ignored))
}
}
+static int
+PyCFuncPtr_set_variadic(PyCFuncPtrObject *self, PyObject *ob)
+{
+ StgDictObject *dict = PyObject_stgdict((PyObject *)self);
+ assert(dict);
+ int r = PyObject_IsTrue(ob);
+ if (r == 1) {
+ dict->flags |= FUNCFLAG_VARIADIC;
+ return 0;
+ } else if (r == 0) {
+ dict->flags &= ~FUNCFLAG_VARIADIC;
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+static PyObject *
+PyCFuncPtr_get_variadic(PyCFuncPtrObject *self)
+{
+ StgDictObject *dict = PyObject_stgdict((PyObject *)self);
+ assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
+ if (dict->flags & FUNCFLAG_VARIADIC)
+ Py_RETURN_TRUE;
+ else
+ Py_RETURN_FALSE;
+}
+
static int
PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored))
{
@@ -3219,6 +3247,8 @@ static PyGetSetDef PyCFuncPtr_getsets[] = {
{ "argtypes", (getter)PyCFuncPtr_get_argtypes,
(setter)PyCFuncPtr_set_argtypes,
"specify the argument types", NULL },
+ { "variadic", (getter)PyCFuncPtr_get_variadic, (setter)PyCFuncPtr_set_variadic,
+ "specify if function takes variable number of arguments", NULL },
{ NULL, NULL }
};
@@ -5632,6 +5662,7 @@ PyInit__ctypes(void)
PyModule_AddObject(m, "FUNCFLAG_USE_ERRNO", PyLong_FromLong(FUNCFLAG_USE_ERRNO));
PyModule_AddObject(m, "FUNCFLAG_USE_LASTERROR", PyLong_FromLong(FUNCFLAG_USE_LASTERROR));
PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyLong_FromLong(FUNCFLAG_PYTHONAPI));
+ PyModule_AddObject(m, "FUNCFLAG_VARIADIC", PyLong_FromLong(FUNCFLAG_VARIADIC));
PyModule_AddStringConstant(m, "__version__", "1.1.0");
PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove));
diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c
index 9cbf9801ad..e7fe11176b 100644
--- a/Modules/_ctypes/callproc.c
+++ b/Modules/_ctypes/callproc.c
@@ -754,7 +756,8 @@ static int _call_function_pointer(int flags,
ffi_type **atypes,
ffi_type *restype,
void *resmem,
- int argcount)
+ int argcount,
+ int argtypecount)
{
PyThreadState *_save = NULL; /* For Py_BLOCK_THREADS and Py_UNBLOCK_THREADS */
PyObject *error_object = NULL;
@@ -780,15 +783,39 @@ static int _call_function_pointer(int flags,
if ((flags & FUNCFLAG_CDECL) == 0)
cc = FFI_STDCALL;
#endif
- if (FFI_OK != ffi_prep_cif(&cif,
- cc,
- argcount,
- restype,
- atypes)) {
- PyErr_SetString(PyExc_RuntimeError,
- "ffi_prep_cif failed");
- return -1;
+
+#if HAVE_FFI_PREP_CIF_VAR
+ /* Everyone SHOULD set f.variadic=True on variadic function pointers, but
+ * lots of existing code will not. If there's at least one arg and more
+ * args are passed than are defined in the prototype, then it must be a
+ * variadic function. */
+ if ((flags & FUNCFLAG_VARIADIC) ||
+ (argtypecount != 0 && argcount > argtypecount))
+ {
+ if (FFI_OK != ffi_prep_cif_var(&cif,
+ cc,
+ argtypecount,
+ argcount,
+ restype,
+ atypes)) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "ffi_prep_cif_var failed");
+ return -1;
+ }
+ } else {
+#endif
+ if (FFI_OK != ffi_prep_cif(&cif,
+ cc,
+ argcount,
+ restype,
+ atypes)) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "ffi_prep_cif failed");
+ return -1;
+ }
+#if HAVE_FFI_PREP_CIF_VAR
}
+#endif
if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) {
error_object = _ctypes_get_errobj(&space);
@@ -1187,9 +1214,8 @@ PyObject *_ctypes_callproc(PPROC pProc,
if (-1 == _call_function_pointer(flags, pProc, avalues, atypes,
rtype, resbuf,
- Py_SAFE_DOWNCAST(argcount,
- Py_ssize_t,
- int)))
+ Py_SAFE_DOWNCAST(argcount, Py_ssize_t, int),
+ Py_SAFE_DOWNCAST(argtype_count, Py_ssize_t, int)))
goto cleanup;
#ifdef WORDS_BIGENDIAN
diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h
index e58f85233c..e45975f6ad 100644
--- a/Modules/_ctypes/ctypes.h
+++ b/Modules/_ctypes/ctypes.h
@@ -285,6 +285,7 @@ PyObject *_ctypes_callproc(PPROC pProc,
#define FUNCFLAG_PYTHONAPI 0x4
#define FUNCFLAG_USE_ERRNO 0x8
#define FUNCFLAG_USE_LASTERROR 0x10
+#define FUNCFLAG_VARIADIC 0x20
#define TYPEFLAG_ISPOINTER 0x100
#define TYPEFLAG_HASPOINTER 0x200
diff --git a/setup.py b/setup.py
index bf90600eaa..48ff120e9a 100644
--- a/setup.py
+++ b/setup.py
@@ -142,6 +142,13 @@ def macosx_sdk_root():
return MACOS_SDK_ROOT
+def is_macosx_at_least(vers):
+ if host_platform == 'darwin':
+ dep_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
+ if dep_target:
+ return tuple(map(int, str(dep_target).split('.'))) >= vers
+ return False
+
def is_macosx_sdk_path(path):
"""
Returns True if 'path' can be located in an OSX SDK
@@ -150,6 +157,13 @@ def is_macosx_sdk_path(path):
or path.startswith('/System/')
or path.startswith('/Library/') )
+def grep_headers_for(function, headers):
+ for header in headers:
+ with open(header, 'r') as f:
+ if function in f.read():
+ return True
+ return False
+
def find_file(filename, std_dirs, paths):
"""Searches for the directory where a given file is located,
and returns a possibly-empty list of additional directories, or None
@@ -1972,7 +1986,11 @@ class PyBuildExt(build_ext):
return True
def detect_ctypes(self, inc_dirs, lib_dirs):
- self.use_system_libffi = False
+ if not sysconfig.get_config_var("LIBFFI_INCLUDEDIR") and is_macosx_at_least((10,15)):
+ self.use_system_libffi = True
+ else:
+ self.use_system_libffi = '--with-system-ffi' in sysconfig.get_config_var("CONFIG_ARGS")
+
include_dirs = []
extra_compile_args = []
extra_link_args = []
@@ -2018,30 +2036,47 @@ class PyBuildExt(build_ext):
libraries=['m'])
self.extensions.extend([ext, ext_test])
+ ffi_inc = sysconfig.get_config_var("LIBFFI_INCLUDEDIR")
+ ffi_lib = None
+
if host_platform == 'darwin':
- if '--with-system-ffi' not in sysconfig.get_config_var("CONFIG_ARGS"):
+ if not self.use_system_libffi:
return
- # OS X 10.5 comes with libffi.dylib; the include files are
- # in /usr/include/ffi
- inc_dirs.append('/usr/include/ffi')
-
- ffi_inc = [sysconfig.get_config_var("LIBFFI_INCLUDEDIR")]
- if not ffi_inc or ffi_inc[0] == '':
- ffi_inc = find_file('ffi.h', [], inc_dirs)
- if ffi_inc is not None:
- ffi_h = ffi_inc[0] + '/ffi.h'
+ ffi_in_sdk = os.path.join(macosx_sdk_root(), "usr/include/ffi")
+ if os.path.exists(ffi_in_sdk):
+ ffi_inc = ffi_in_sdk
+ ffi_lib = 'ffi'
+ else:
+ # OS X 10.5 comes with libffi.dylib; the include files are
+ # in /usr/include/ffi
+ inc_dirs.append('/usr/include/ffi')
+
+ if not ffi_inc:
+ found = find_file('ffi.h', [], inc_dirs)
+ if found:
+ ffi_inc = found[0]
+ if ffi_inc:
+ ffi_h = ffi_inc + '/ffi.h'
if not os.path.exists(ffi_h):
ffi_inc = None
print('Header file {} does not exist'.format(ffi_h))
- ffi_lib = None
- if ffi_inc is not None:
- for lib_name in ('ffi', 'ffi_pic'):
+
+ if ffi_lib is None and ffi_inc:
+ for lib_name in ('ffi_convenience', 'ffi_pic', 'ffi'):
if (self.compiler.find_library_file(lib_dirs, lib_name)):
ffi_lib = lib_name
break
if ffi_inc and ffi_lib:
- ext.include_dirs.extend(ffi_inc)
+ ffi_headers = glob(os.path.join(ffi_inc, '*.h'))
+ if grep_headers_for('ffi_closure_alloc', ffi_headers):
+ try:
+ sources.remove('_ctypes/malloc_closure.c')
+ except ValueError:
+ pass
+ if grep_headers_for('ffi_prep_cif_var', ffi_headers):
+ ext.extra_compile_args.append("-DHAVE_FFI_PREP_CIF_VAR=1")
+ ext.include_dirs.append(ffi_inc)
ext.libraries.append(ffi_lib)
self.use_system_libffi = True
--
2.30.1 (Apple Git-130)

View File

@@ -0,0 +1,37 @@
From f2595c038ed7bfd182d9d05d83786106ebd02ca0 Mon Sep 17 00:00:00 2001
From: Lawrence D'Anna <64555057+lawrence-danna-apple@users.noreply.github.com>
Date: Tue, 30 Jun 2020 02:15:46 -0700
Subject: [PATCH] bpo-41100: fix _decimal for arm64 Mac OS (GH-21228)
Patch by Lawrence Danna.
---
.../Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst | 1 +
Modules/_decimal/libmpdec/mpdecimal.h | 3 +++
2 files changed, 4 insertions(+)
create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst
diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst
new file mode 100644
index 0000000000..d6176d69f0
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst
@@ -0,0 +1 @@
+add arm64 to the allowable Mac OS arches in mpdecimal.h
\ No newline at end of file
diff --git a/Modules/_decimal/libmpdec/mpdecimal.h b/Modules/_decimal/libmpdec/mpdecimal.h
index a67dd9bc12..3e9c8185c3 100644
--- a/Modules/_decimal/libmpdec/mpdecimal.h
+++ b/Modules/_decimal/libmpdec/mpdecimal.h
@@ -135,6 +135,9 @@ const char *mpd_version(void);
#elif defined(__x86_64__)
#define CONFIG_64
#define ASM
+ #elif defined(__arm64__)
+ #define CONFIG_64
+ #define ANSI
#else
#error "unknown architecture for universal build."
#endif
--
2.37.3

View File

@@ -0,0 +1,30 @@
From 245427d207ee88a4ba26a66c3de350bcbcc036f2 Mon Sep 17 00:00:00 2001
From: Ronald Oussoren <ronaldoussoren@mac.com>
Date: Sat, 14 Nov 2020 16:07:47 +0100
Subject: [PATCH] bpo-42351: Avoid error when opening header with non-UTF8
encoding (GH-23279)
grep_headers_for() would error out when a header contained
text that cannot be interpreted as UTF-8.
cherry-picked from 7a27c7ed4b by Pedro Fonini <fonini@ip.tv>
---
setup.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/setup.py b/setup.py
index f211989aac..467362813d 100644
--- a/setup.py
+++ b/setup.py
@@ -159,7 +159,7 @@ def is_macosx_sdk_path(path):
def grep_headers_for(function, headers):
for header in headers:
- with open(header, 'r') as f:
+ with open(header, 'r', errors='surrogateescape') as f:
if function in f.read():
return True
return False
--
2.34.1

View File

@@ -0,0 +1,310 @@
From: Christian Hammond <christian@beanbaginc.com>
Date: Wed, 15 Dec 2021 23:12:36 -0800
Subject: Port ctypes and system libffi patches for arm64/macOS 10.15+ to Python 3.7.12
This ports the following ctypes and libffi pyenv patches for Python
2.7.18 to Python 3.7.12:
* `0004-Use-system-libffi-for-Mac-OS-10.15-and-up.patch`
* `0005-ctypes-use-the-correct-ABI-for-variadic-functions.patch`
* `0006-ctypes-probe-libffi-for-ffi_closure_alloc-and-ffi_pr.patch`
These patches enable use of system libffi (fixing a broken `ctypes`
module on arm64 targets) and enable calling variadic functions on arm64.
They've been combined from patches port from Homebrew to pyenv by Takumi
Sueda, updated to work on the Python 3.7.12 codebase.
The Homebrew patches are themselves backports of changes in Python 3.9
and 3.10. That patch can be found at:
https://github.com/Homebrew/formula-patches/blob/master/python/3.8.7.patch
diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst
index 715d595b24..7743144978 100644
--- a/Doc/library/ctypes.rst
+++ b/Doc/library/ctypes.rst
@@ -1551,6 +1551,13 @@ They are instances of a private class:
value usable as argument (integer, string, ctypes instance). This allows
defining adapters that can adapt custom objects as function parameters.
+ .. attribute:: variadic
+
+ Assign a boolean to specify that the function takes a variable number of
+ arguments. This does not matter on most platforms, but for Apple arm64
+ platforms variadic functions have a different calling convention than
+ normal functions.
+
.. attribute:: errcheck
Assign a Python function or another callable to this attribute. The
diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py
index 4ebd82d3e0..7b73c190b6 100644
--- a/Lib/test/test_unicode.py
+++ b/Lib/test/test_unicode.py
@@ -2458,11 +2458,14 @@ class CAPITest(unittest.TestCase):
def test_from_format(self):
support.import_module('ctypes')
from ctypes import (
+ c_char_p,
pythonapi, py_object, sizeof,
c_int, c_long, c_longlong, c_ssize_t,
c_uint, c_ulong, c_ulonglong, c_size_t, c_void_p)
name = "PyUnicode_FromFormat"
_PyUnicode_FromFormat = getattr(pythonapi, name)
+ _PyUnicode_FromFormat.argtypes = (c_char_p,)
+ _PyUnicode_FromFormat.variadic = True
_PyUnicode_FromFormat.restype = py_object
def PyUnicode_FromFormat(format, *args):
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
index dd0c61fd8a..79137e1dc7 100644
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -3174,6 +3174,34 @@ PyCFuncPtr_get_restype(PyCFuncPtrObject *self, void *Py_UNUSED(ignored))
}
}
+static int
+PyCFuncPtr_set_variadic(PyCFuncPtrObject *self, PyObject *ob)
+{
+ StgDictObject *dict = PyObject_stgdict((PyObject *)self);
+ assert(dict);
+ int r = PyObject_IsTrue(ob);
+ if (r == 1) {
+ dict->flags |= FUNCFLAG_VARIADIC;
+ return 0;
+ } else if (r == 0) {
+ dict->flags &= ~FUNCFLAG_VARIADIC;
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+static PyObject *
+PyCFuncPtr_get_variadic(PyCFuncPtrObject *self)
+{
+ StgDictObject *dict = PyObject_stgdict((PyObject *)self);
+ assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
+ if (dict->flags & FUNCFLAG_VARIADIC)
+ Py_RETURN_TRUE;
+ else
+ Py_RETURN_FALSE;
+}
+
static int
PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored))
{
@@ -3219,6 +3247,8 @@ static PyGetSetDef PyCFuncPtr_getsets[] = {
{ "argtypes", (getter)PyCFuncPtr_get_argtypes,
(setter)PyCFuncPtr_set_argtypes,
"specify the argument types", NULL },
+ { "variadic", (getter)PyCFuncPtr_get_variadic, (setter)PyCFuncPtr_set_variadic,
+ "specify if function takes variable number of arguments", NULL },
{ NULL, NULL }
};
@@ -5632,6 +5662,7 @@ PyInit__ctypes(void)
PyModule_AddObject(m, "FUNCFLAG_USE_ERRNO", PyLong_FromLong(FUNCFLAG_USE_ERRNO));
PyModule_AddObject(m, "FUNCFLAG_USE_LASTERROR", PyLong_FromLong(FUNCFLAG_USE_LASTERROR));
PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyLong_FromLong(FUNCFLAG_PYTHONAPI));
+ PyModule_AddObject(m, "FUNCFLAG_VARIADIC", PyLong_FromLong(FUNCFLAG_VARIADIC));
PyModule_AddStringConstant(m, "__version__", "1.1.0");
PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove));
diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c
index 9cbf9801ad..e7fe11176b 100644
--- a/Modules/_ctypes/callproc.c
+++ b/Modules/_ctypes/callproc.c
@@ -754,7 +756,8 @@ static int _call_function_pointer(int flags,
ffi_type **atypes,
ffi_type *restype,
void *resmem,
- int argcount)
+ int argcount,
+ int argtypecount)
{
PyThreadState *_save = NULL; /* For Py_BLOCK_THREADS and Py_UNBLOCK_THREADS */
PyObject *error_object = NULL;
@@ -780,15 +783,39 @@ static int _call_function_pointer(int flags,
if ((flags & FUNCFLAG_CDECL) == 0)
cc = FFI_STDCALL;
#endif
- if (FFI_OK != ffi_prep_cif(&cif,
- cc,
- argcount,
- restype,
- atypes)) {
- PyErr_SetString(PyExc_RuntimeError,
- "ffi_prep_cif failed");
- return -1;
+
+#if HAVE_FFI_PREP_CIF_VAR
+ /* Everyone SHOULD set f.variadic=True on variadic function pointers, but
+ * lots of existing code will not. If there's at least one arg and more
+ * args are passed than are defined in the prototype, then it must be a
+ * variadic function. */
+ if ((flags & FUNCFLAG_VARIADIC) ||
+ (argtypecount != 0 && argcount > argtypecount))
+ {
+ if (FFI_OK != ffi_prep_cif_var(&cif,
+ cc,
+ argtypecount,
+ argcount,
+ restype,
+ atypes)) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "ffi_prep_cif_var failed");
+ return -1;
+ }
+ } else {
+#endif
+ if (FFI_OK != ffi_prep_cif(&cif,
+ cc,
+ argcount,
+ restype,
+ atypes)) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "ffi_prep_cif failed");
+ return -1;
+ }
+#if HAVE_FFI_PREP_CIF_VAR
}
+#endif
if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) {
error_object = _ctypes_get_errobj(&space);
@@ -1187,9 +1214,8 @@ PyObject *_ctypes_callproc(PPROC pProc,
if (-1 == _call_function_pointer(flags, pProc, avalues, atypes,
rtype, resbuf,
- Py_SAFE_DOWNCAST(argcount,
- Py_ssize_t,
- int)))
+ Py_SAFE_DOWNCAST(argcount, Py_ssize_t, int),
+ Py_SAFE_DOWNCAST(argtype_count, Py_ssize_t, int)))
goto cleanup;
#ifdef WORDS_BIGENDIAN
diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h
index e58f85233c..e45975f6ad 100644
--- a/Modules/_ctypes/ctypes.h
+++ b/Modules/_ctypes/ctypes.h
@@ -285,6 +285,7 @@ PyObject *_ctypes_callproc(PPROC pProc,
#define FUNCFLAG_PYTHONAPI 0x4
#define FUNCFLAG_USE_ERRNO 0x8
#define FUNCFLAG_USE_LASTERROR 0x10
+#define FUNCFLAG_VARIADIC 0x20
#define TYPEFLAG_ISPOINTER 0x100
#define TYPEFLAG_HASPOINTER 0x200
diff --git a/setup.py b/setup.py
index bf90600eaa..48ff120e9a 100644
--- a/setup.py
+++ b/setup.py
@@ -142,6 +142,13 @@ def macosx_sdk_root():
return MACOS_SDK_ROOT
+def is_macosx_at_least(vers):
+ if host_platform == 'darwin':
+ dep_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
+ if dep_target:
+ return tuple(map(int, str(dep_target).split('.'))) >= vers
+ return False
+
def is_macosx_sdk_path(path):
"""
Returns True if 'path' can be located in an OSX SDK
@@ -150,6 +157,13 @@ def is_macosx_sdk_path(path):
or path.startswith('/System/')
or path.startswith('/Library/') )
+def grep_headers_for(function, headers):
+ for header in headers:
+ with open(header, 'r') as f:
+ if function in f.read():
+ return True
+ return False
+
def find_file(filename, std_dirs, paths):
"""Searches for the directory where a given file is located,
and returns a possibly-empty list of additional directories, or None
@@ -1972,7 +1986,11 @@ class PyBuildExt(build_ext):
return True
def detect_ctypes(self, inc_dirs, lib_dirs):
- self.use_system_libffi = False
+ if not sysconfig.get_config_var("LIBFFI_INCLUDEDIR") and is_macosx_at_least((10,15)):
+ self.use_system_libffi = True
+ else:
+ self.use_system_libffi = '--with-system-ffi' in sysconfig.get_config_var("CONFIG_ARGS")
+
include_dirs = []
extra_compile_args = []
extra_link_args = []
@@ -2018,30 +2036,47 @@ class PyBuildExt(build_ext):
libraries=['m'])
self.extensions.extend([ext, ext_test])
+ ffi_inc = sysconfig.get_config_var("LIBFFI_INCLUDEDIR")
+ ffi_lib = None
+
if host_platform == 'darwin':
- if '--with-system-ffi' not in sysconfig.get_config_var("CONFIG_ARGS"):
+ if not self.use_system_libffi:
return
- # OS X 10.5 comes with libffi.dylib; the include files are
- # in /usr/include/ffi
- inc_dirs.append('/usr/include/ffi')
-
- ffi_inc = [sysconfig.get_config_var("LIBFFI_INCLUDEDIR")]
- if not ffi_inc or ffi_inc[0] == '':
- ffi_inc = find_file('ffi.h', [], inc_dirs)
- if ffi_inc is not None:
- ffi_h = ffi_inc[0] + '/ffi.h'
+ ffi_in_sdk = os.path.join(macosx_sdk_root(), "usr/include/ffi")
+ if os.path.exists(ffi_in_sdk):
+ ffi_inc = ffi_in_sdk
+ ffi_lib = 'ffi'
+ else:
+ # OS X 10.5 comes with libffi.dylib; the include files are
+ # in /usr/include/ffi
+ inc_dirs.append('/usr/include/ffi')
+
+ if not ffi_inc:
+ found = find_file('ffi.h', [], inc_dirs)
+ if found:
+ ffi_inc = found[0]
+ if ffi_inc:
+ ffi_h = ffi_inc + '/ffi.h'
if not os.path.exists(ffi_h):
ffi_inc = None
print('Header file {} does not exist'.format(ffi_h))
- ffi_lib = None
- if ffi_inc is not None:
- for lib_name in ('ffi', 'ffi_pic'):
+
+ if ffi_lib is None and ffi_inc:
+ for lib_name in ('ffi_convenience', 'ffi_pic', 'ffi'):
if (self.compiler.find_library_file(lib_dirs, lib_name)):
ffi_lib = lib_name
break
if ffi_inc and ffi_lib:
- ext.include_dirs.extend(ffi_inc)
+ ffi_headers = glob(os.path.join(ffi_inc, '*.h'))
+ if grep_headers_for('ffi_closure_alloc', ffi_headers):
+ try:
+ sources.remove('_ctypes/malloc_closure.c')
+ except ValueError:
+ pass
+ if grep_headers_for('ffi_prep_cif_var', ffi_headers):
+ ext.extra_compile_args.append("-DHAVE_FFI_PREP_CIF_VAR=1")
+ ext.include_dirs.append(ffi_inc)
ext.libraries.append(ffi_lib)
self.use_system_libffi = True
--
2.30.1 (Apple Git-130)

View File

@@ -0,0 +1,37 @@
From f2595c038ed7bfd182d9d05d83786106ebd02ca0 Mon Sep 17 00:00:00 2001
From: Lawrence D'Anna <64555057+lawrence-danna-apple@users.noreply.github.com>
Date: Tue, 30 Jun 2020 02:15:46 -0700
Subject: [PATCH] bpo-41100: fix _decimal for arm64 Mac OS (GH-21228)
Patch by Lawrence Danna.
---
.../Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst | 1 +
Modules/_decimal/libmpdec/mpdecimal.h | 3 +++
2 files changed, 4 insertions(+)
create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst
diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst
new file mode 100644
index 0000000000..d6176d69f0
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst
@@ -0,0 +1 @@
+add arm64 to the allowable Mac OS arches in mpdecimal.h
\ No newline at end of file
diff --git a/Modules/_decimal/libmpdec/mpdecimal.h b/Modules/_decimal/libmpdec/mpdecimal.h
index a67dd9bc12..3e9c8185c3 100644
--- a/Modules/_decimal/libmpdec/mpdecimal.h
+++ b/Modules/_decimal/libmpdec/mpdecimal.h
@@ -135,6 +135,9 @@ const char *mpd_version(void);
#elif defined(__x86_64__)
#define CONFIG_64
#define ASM
+ #elif defined(__arm64__)
+ #define CONFIG_64
+ #define ANSI
#else
#error "unknown architecture for universal build."
#endif
--
2.37.3

View File

@@ -0,0 +1,30 @@
From 245427d207ee88a4ba26a66c3de350bcbcc036f2 Mon Sep 17 00:00:00 2001
From: Ronald Oussoren <ronaldoussoren@mac.com>
Date: Sat, 14 Nov 2020 16:07:47 +0100
Subject: [PATCH] bpo-42351: Avoid error when opening header with non-UTF8
encoding (GH-23279)
grep_headers_for() would error out when a header contained
text that cannot be interpreted as UTF-8.
cherry-picked from 7a27c7ed4b by Pedro Fonini <fonini@ip.tv>
---
setup.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/setup.py b/setup.py
index f211989aac..467362813d 100644
--- a/setup.py
+++ b/setup.py
@@ -159,7 +159,7 @@ def is_macosx_sdk_path(path):
def grep_headers_for(function, headers):
for header in headers:
- with open(header, 'r') as f:
+ with open(header, 'r', errors='surrogateescape') as f:
if function in f.read():
return True
return False
--
2.34.1

View File

@@ -0,0 +1,12 @@
diff --git a/test/v3ext.c b/test/v3ext.c
index 7a240cd706..6cec6f1a9b 100644
--- a/test/v3ext.c
+++ b/test/v3ext.c
@@ -15,6 +15,7 @@
#include <openssl/err.h>
#include "internal/nelem.h"
+#include <string.h>
#include "testutil.h"
static const char *infile;

View File

@@ -0,0 +1,12 @@
diff --git a/test/v3ext.c b/test/v3ext.c
index 7a240cd706..6cec6f1a9b 100644
--- a/test/v3ext.c
+++ b/test/v3ext.c
@@ -15,6 +15,7 @@
#include <openssl/err.h>
#include "internal/nelem.h"
+#include <string.h>
#include "testutil.h"
static const char *infile;

View File

@@ -0,0 +1,23 @@
# sha256sum used for checksum values
# version of pyston
VER='2.3.5'
# alias for download location
DOWNLOAD='https://github.com/pyston/pyston/releases/download'
case "$(pyston_architecture 2>/dev/null || true)" in
"linux64" )
install_package "pyston_${VER}_portable_amd64" "${DOWNLOAD}/pyston_${VER}/pyston_${VER}_portable_amd64.tar.gz#c71c711d60a9c18f243a9e30fd35e0818674ae96f534c67c27b0cdfbc9132ef8" "pyston" verify_py38 get_pip
;;
"linux-aarch64" )
install_package "pyston_${VER}_portable_arm64" "${DOWNLOAD}/pyston_${VER}/pyston_${VER}_portable_arm64.tar.gz#c578cb806c62d9dca8728f190a87e172305bd80887e206df42c4c5658ab469c1" "pyston" verify_py38 get_pip
;;
* )
{ echo
colorize 1 "ERROR"
echo ": A Pyston ${VER} binary is not available for $(pyston_architecture 2>/dev/null || true)."
echo
} >&2
exit 1
;;
esac

View File

@@ -35,7 +35,7 @@ tarball() {
executable "$configure" <<OUT
#!$BASH
echo "$name: CPPFLAGS=\\"\$CPPFLAGS\\" LDFLAGS=\\"\$LDFLAGS\\"" >> build.log
echo "$name: CPPFLAGS=\\"\$CPPFLAGS\\" LDFLAGS=\\"\$LDFLAGS\\" PKG_CONFIG_PATH=\\"\$PKG_CONFIG_PATH\\"" >> build.log
echo "$name: \$@" \${PYTHONOPT:+PYTHONOPT=\$PYTHONOPT} >> build.log
OUT
@@ -74,11 +74,11 @@ assert_build_log() {
unstub make
assert_build_log <<OUT
yaml-0.1.6: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib "
yaml-0.1.6: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib " PKG_CONFIG_PATH=""
yaml-0.1.6: --prefix=$INSTALL_ROOT
make -j 2
make install
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib "
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib " PKG_CONFIG_PATH=""
Python-3.6.2: --prefix=$INSTALL_ROOT --libdir=$INSTALL_ROOT/lib
make -j 2
make install
@@ -103,12 +103,12 @@ OUT
unstub patch
assert_build_log <<OUT
yaml-0.1.6: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib "
yaml-0.1.6: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib " PKG_CONFIG_PATH=""
yaml-0.1.6: --prefix=$INSTALL_ROOT
make -j 2
make install
patch -p0 --force -i $TMP/python-patch.XXX
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib "
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib " PKG_CONFIG_PATH=""
Python-3.6.2: --prefix=$INSTALL_ROOT --libdir=$INSTALL_ROOT/lib
make -j 2
make install
@@ -133,12 +133,12 @@ OUT
unstub patch
assert_build_log <<OUT
yaml-0.1.6: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib "
yaml-0.1.6: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib " PKG_CONFIG_PATH=""
yaml-0.1.6: --prefix=$INSTALL_ROOT
make -j 2
make install
patch -p1 --force -i $TMP/python-patch.XXX
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib "
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib " PKG_CONFIG_PATH=""
Python-3.6.2: --prefix=$INSTALL_ROOT --libdir=$INSTALL_ROOT/lib
make -j 2
make install
@@ -151,7 +151,7 @@ OUT
BREW_PREFIX="$TMP/homebrew-prefix"
mkdir -p "$BREW_PREFIX"
for i in {1..9}; do stub uname '-s : echo Darwin'; done
for i in {1..8}; do stub uname '-s : echo Darwin'; done
for i in {1..2}; do stub sw_vers '-productVersion : echo 1010'; done
stub brew "--prefix : echo '$BREW_PREFIX'" false
stub_make_install
@@ -166,7 +166,7 @@ DEF
unstub make
assert_build_log <<OUT
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include -I$BREW_PREFIX/include" LDFLAGS="-L${TMP}/install/lib -L$BREW_PREFIX/lib -Wl,-rpath,$BREW_PREFIX/lib"
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include -I$BREW_PREFIX/include" LDFLAGS="-L${TMP}/install/lib -L$BREW_PREFIX/lib -Wl,-rpath,$BREW_PREFIX/lib" PKG_CONFIG_PATH=""
Python-3.6.2: --prefix=$INSTALL_ROOT --libdir=$INSTALL_ROOT/lib
make -j 2
make install
@@ -179,7 +179,7 @@ OUT
brew_libdir="$TMP/homebrew-yaml"
mkdir -p "$brew_libdir"
for i in {1..10}; do stub uname '-s : echo Darwin'; done
for i in {1..9}; do stub uname '-s : echo Darwin'; done
for i in {1..2}; do stub sw_vers '-productVersion : echo 1010'; done
stub brew "--prefix libyaml : echo '$brew_libdir'"
for i in {1..4}; do stub brew false; done
@@ -194,7 +194,7 @@ OUT
unstub make
assert_build_log <<OUT
Python-3.6.2: CPPFLAGS="-I$brew_libdir/include -I${TMP}/install/include " LDFLAGS="-L$brew_libdir/lib -L${TMP}/install/lib "
Python-3.6.2: CPPFLAGS="-I$brew_libdir/include -I${TMP}/install/include " LDFLAGS="-L$brew_libdir/lib -L${TMP}/install/lib " PKG_CONFIG_PATH=""
Python-3.6.2: --prefix=$INSTALL_ROOT --libdir=$INSTALL_ROOT/lib
make -j 2
make install
@@ -218,11 +218,11 @@ OUT
unstub make
assert_build_log <<OUT
yaml-0.1.6: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib "
yaml-0.1.6: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib " PKG_CONFIG_PATH=""
yaml-0.1.6: --prefix=${TMP}/install
make -j 2
make install
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib "
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib " PKG_CONFIG_PATH=""
Python-3.6.2: --prefix=$INSTALL_ROOT --libdir=$INSTALL_ROOT/lib
make -j 2
make install
@@ -234,7 +234,7 @@ OUT
readline_libdir="$TMP/homebrew-readline"
mkdir -p "$readline_libdir"
for i in {1..8}; do stub uname '-s : echo Darwin'; done
for i in {1..7}; do stub uname '-s : echo Darwin'; done
for i in {1..2}; do stub sw_vers '-productVersion : echo 1010'; done
for i in {1..2}; do stub brew false; done
stub brew "--prefix readline : echo '$readline_libdir'"
@@ -252,7 +252,7 @@ DEF
unstub make
assert_build_log <<OUT
Python-3.6.2: CPPFLAGS="-I$readline_libdir/include -I${TMP}/install/include " LDFLAGS="-L$readline_libdir/lib -L${TMP}/install/lib "
Python-3.6.2: CPPFLAGS="-I$readline_libdir/include -I${TMP}/install/include " LDFLAGS="-L$readline_libdir/lib -L${TMP}/install/lib " PKG_CONFIG_PATH=""
Python-3.6.2: --prefix=$INSTALL_ROOT --libdir=$INSTALL_ROOT/lib
make -j 2
make install
@@ -276,7 +276,33 @@ DEF
unstub make
assert_build_log <<OUT
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib "
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib " PKG_CONFIG_PATH=""
Python-3.6.2: --prefix=$INSTALL_ROOT --libdir=$INSTALL_ROOT/lib
make -j 2
make install
OUT
}
@test "no library searches performed during normal operation touch homebrew if envvar is set" {
cached_tarball "Python-3.6.2"
for i in {1..4}; do stub uname '-s : echo Darwin'; done
for i in {1..2}; do stub sw_vers '-productVersion : echo 1010'; done
stub brew true; brew
stub_make_install
export PYTHON_BUILD_SKIP_HOMEBREW=1
run_inline_definition <<DEF
install_package "Python-3.6.2" "http://python.org/ftp/python/3.6.2/Python-3.6.2.tar.gz"
DEF
assert_success
unstub uname
unstub brew
unstub make
assert_build_log <<OUT
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib " PKG_CONFIG_PATH=""
Python-3.6.2: --prefix=$INSTALL_ROOT --libdir=$INSTALL_ROOT/lib
make -j 2
make install
@@ -291,7 +317,7 @@ OUT
mkdir -p "$readline_libdir/include/readline"
touch "$readline_libdir/include/readline/rlconf.h"
for i in {1..8}; do stub uname '-s : echo Darwin'; done
for i in {1..7}; do stub uname '-s : echo Darwin'; done
for i in {1..2}; do stub sw_vers '-productVersion : echo 1010'; done
for i in {1..3}; do stub brew false; done
@@ -309,7 +335,7 @@ DEF
unstub make
assert_build_log <<OUT
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib "
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib " PKG_CONFIG_PATH=""
Python-3.6.2: --prefix=$INSTALL_ROOT CPPFLAGS=-I$readline_libdir/include LDFLAGS=-L$readline_libdir/lib --libdir=$INSTALL_ROOT/lib
make -j 2
make install
@@ -323,7 +349,7 @@ OUT
mkdir -p "$tcl_tk_libdir/lib"
echo "TCL_VERSION='$tcl_tk_version'" >>"$tcl_tk_libdir/lib/tclConfig.sh"
for i in {1..10}; do stub uname '-s : echo Darwin'; done
for i in {1..9}; do stub uname '-s : echo Darwin'; done
for i in {1..2}; do stub sw_vers '-productVersion : echo 1010'; done
stub brew false
@@ -343,7 +369,7 @@ DEF
unstub make
assert_build_log <<OUT
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib "
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib " PKG_CONFIG_PATH="${TMP}/homebrew-tcl-tk/lib/pkgconfig"
Python-3.6.2: --prefix=${TMP}/install --libdir=${TMP}/install/lib --with-tcltk-libs=-L${TMP}/homebrew-tcl-tk/lib -ltcl$tcl_tk_version -ltk$tcl_tk_version --with-tcltk-includes=-I${TMP}/homebrew-tcl-tk/include
make -j 2
make install
@@ -357,7 +383,7 @@ OUT
tcl_tk_version_long="8.6.10"
tcl_tk_version="${tcl_tk_version_long%.*}"
for i in {1..9}; do stub uname '-s : echo Darwin'; done
for i in {1..8}; do stub uname '-s : echo Darwin'; done
for i in {1..2}; do stub sw_vers '-productVersion : echo 1010'; done
for i in {1..4}; do stub brew false; done
@@ -375,17 +401,50 @@ DEF
unstub make
assert_build_log <<OUT
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib "
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib " PKG_CONFIG_PATH=""
Python-3.6.2: --prefix=$INSTALL_ROOT --libdir=$INSTALL_ROOT/lib --with-tcltk-libs=-L${TMP}/custom-tcl-tk/lib -ltcl8.6 -ltk8.6
make -j 2
make install
OUT
}
@test "tcl-tk is linked from Homebrew via pkgconfig only when envvar is set" {
cached_tarball "Python-3.6.2"
for i in {1..9}; do stub uname '-s : echo Darwin'; done
for i in {1..2}; do stub sw_vers '-productVersion : echo 1010'; done
tcl_tk_libdir="$TMP/homebrew-tcl-tk"
mkdir -p "$tcl_tk_libdir/lib"
stub brew false
for i in {1..2}; do stub brew "--prefix tcl-tk : echo '${tcl_tk_libdir}'"; done
for i in {1..2}; do stub brew false; done
stub_make_install
run_inline_definition <<DEF
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "Python-3.6.2" "http://python.org/ftp/python/3.6.2/Python-3.6.2.tar.gz"
DEF
assert_success
unstub uname
unstub sw_vers
unstub brew
unstub make
assert_build_log <<OUT
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib " PKG_CONFIG_PATH="${TMP}/homebrew-tcl-tk/lib/pkgconfig"
Python-3.6.2: --prefix=${TMP}/install --libdir=${TMP}/install/lib
make -j 2
make install
OUT
}
@test "number of CPU cores defaults to 2" {
cached_tarball "Python-3.6.2"
for i in {1..10}; do stub uname '-s : echo Darwin'; done
for i in {1..9}; do stub uname '-s : echo Darwin'; done
for i in {1..2}; do stub sw_vers '-productVersion : echo 10.10'; done
stub sysctl false
@@ -402,7 +461,7 @@ DEF
unstub make
assert_build_log <<OUT
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib "
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib " PKG_CONFIG_PATH=""
Python-3.6.2: --prefix=$INSTALL_ROOT --libdir=$INSTALL_ROOT/lib
make -j 2
make install
@@ -412,7 +471,7 @@ OUT
@test "number of CPU cores is detected on Mac" {
cached_tarball "Python-3.6.2"
for i in {1..10}; do stub uname '-s : echo Darwin'; done
for i in {1..9}; do stub uname '-s : echo Darwin'; done
for i in {1..2}; do stub sw_vers '-productVersion : echo 10.10'; done
stub sysctl '-n hw.ncpu : echo 4'
@@ -430,7 +489,7 @@ DEF
unstub make
assert_build_log <<OUT
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib "
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib " PKG_CONFIG_PATH=""
Python-3.6.2: --prefix=$INSTALL_ROOT --libdir=$INSTALL_ROOT/lib
make -j 4
make install
@@ -458,7 +517,7 @@ DEF
unstub make
assert_build_log <<OUT
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib "
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib " PKG_CONFIG_PATH=""
Python-3.6.2: --prefix=$INSTALL_ROOT --libdir=$INSTALL_ROOT/lib
make -j 1
make install
@@ -482,21 +541,48 @@ DEF
unstub make
assert_build_log <<OUT
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib "
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib " PKG_CONFIG_PATH=""
Python-3.6.2: --prefix=$INSTALL_ROOT --libdir=$INSTALL_ROOT/lib
make -j 2
make install DOGE="such wow"
OUT
}
@test "setting MAKE_INSTALL_OPTS to a multi-word string" {
@test "configuring with dSYM in MacOS" {
cached_tarball "Python-3.6.2"
for i in {1..8}; do stub uname '-s : echo Linux'; done
for i in {1..9}; do stub uname '-s : echo Darwin'; done
for i in {1..2}; do stub sw_vers '-productVersion : echo 1010'; done
for i in {1..4}; do stub brew false; done
stub_make_install
export MAKE_INSTALL_OPTS="DOGE=\"such wow\""
run_inline_definition <<DEF
export PYTHON_BUILD_CONFIGURE_WITH_DSYMUTIL=1
install_package "Python-3.6.2" "http://python.org/ftp/python/3.6.2/Python-3.6.2.tar.gz"
DEF
assert_success
unstub sw_vers
unstub uname
unstub brew
unstub make
assert_build_log <<OUT
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib " PKG_CONFIG_PATH=""
Python-3.6.2: --prefix=$INSTALL_ROOT --libdir=${TMP}/install/lib --with-dsymutil
make -j 2
make install
OUT
}
@test "configuring with dSYM has no effect in non-MacOS" {
cached_tarball "Python-3.6.2"
for i in {1..9}; do stub uname '-s : echo Linux'; done
stub_make_install
run_inline_definition <<DEF
export PYTHON_BUILD_CONFIGURE_WITH_DSYMUTIL=1
install_package "Python-3.6.2" "http://python.org/ftp/python/3.6.2/Python-3.6.2.tar.gz"
DEF
assert_success
@@ -505,10 +591,10 @@ DEF
unstub make
assert_build_log <<OUT
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib "
Python-3.6.2: --prefix=$INSTALL_ROOT --libdir=$INSTALL_ROOT/lib
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib " PKG_CONFIG_PATH=""
Python-3.6.2: --prefix=$INSTALL_ROOT --libdir=${TMP}/install/lib
make -j 2
make install DOGE="such wow"
make install
OUT
}
@@ -595,7 +681,7 @@ DEF
assert_build_log <<OUT
apply -p1 -i /my/patch.diff
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib "
Python-3.6.2: CPPFLAGS="-I${TMP}/install/include " LDFLAGS="-L${TMP}/install/lib " PKG_CONFIG_PATH=""
Python-3.6.2: --prefix=$INSTALL_ROOT --libdir=$INSTALL_ROOT/lib
make -j 2
make install

View File

@@ -63,7 +63,7 @@ DEF
mkdir -p "$INSTALL_ROOT"
cd "$INSTALL_ROOT"
for i in {1..10}; do stub uname '-s : echo Darwin'; done
for i in {1..9}; do stub uname '-s : echo Darwin'; done
for i in {1..3}; do stub sw_vers '-productVersion : echo 10.10'; done
stub cc 'false'
@@ -115,6 +115,6 @@ DEF
#assert_success
assert_output <<OUT
CFLAGS_EXTRA=-DMICROPY_PY_SYS_PATH_DEFAULT='"${TMP}/install/lib/micropython"' -Wno-floating-conversion
CFLAGS_EXTRA=-DMICROPY_PY_SYS_PATH_DEFAULT='".frozen:${TMP}/install/lib/micropython"' -Wno-floating-conversion
OUT
}

View File

@@ -21,7 +21,7 @@ setup() {
@test "using aria2c if available" {
export PYTHON_BUILD_ARIA2_OPTS=
export -n PYTHON_BUILD_HTTP_CLIENT
stub aria2c "--allow-overwrite=true --no-conf=true -o * http://example.com/* : cp $FIXTURE_ROOT/\${5##*/} \$4"
stub aria2c "--allow-overwrite=true --no-conf=true -d * -o * http://example.com/* : cp $FIXTURE_ROOT/\${7##*/} \$6"
install_fixture definitions/without-checksum
assert_success

View File

@@ -15,6 +15,7 @@ after_install 'echo after: \$STATUS'
OUT
stub pyenv-hooks "install : echo '$HOOK_PATH'/install.bash"
stub pyenv-rehash "echo rehashed"
stub pyenv-latest false
definition="${TMP}/3.6.2"
cat > "$definition" <<<"echo python-build"
@@ -55,3 +56,38 @@ OUT
refute [ -d "${PYENV_ROOT}/versions/3.6.2" ]
}
@test "pyenv-uninstall hooks with multiple versions" {
cat > "${HOOK_PATH}/uninstall.bash" <<OUT
before_uninstall 'echo before: \$PREFIX'
after_uninstall 'echo after.'
rm() {
echo "rm \$@"
command rm "\$@"
}
OUT
stub pyenv-hooks "uninstall : echo '$HOOK_PATH'/uninstall.bash"
stub pyenv-rehash "echo rehashed"
stub pyenv-rehash "echo rehashed"
mkdir -p "${PYENV_ROOT}/versions/3.6.2"
mkdir -p "${PYENV_ROOT}/versions/3.6.3"
run pyenv-uninstall -f 3.6.2 3.6.3
assert_success
assert_output <<-OUT
before: ${PYENV_ROOT}/versions/3.6.2
rm -rf ${PYENV_ROOT}/versions/3.6.2
rehashed
pyenv: 3.6.2 uninstalled
after.
before: ${PYENV_ROOT}/versions/3.6.3
rm -rf ${PYENV_ROOT}/versions/3.6.3
rehashed
pyenv: 3.6.3 uninstalled
after.
OUT
refute [ -d "${PYENV_ROOT}/versions/3.6.2" ]
refute [ -d "${PYENV_ROOT}/versions/3.6.3" ]
}

View File

@@ -10,6 +10,7 @@ setup() {
stub_python_build() {
stub python-build "--lib : $BATS_TEST_DIRNAME/../bin/python-build --lib" "$@"
stub pyenv-latest " : false"
}
@test "install proper" {
@@ -23,6 +24,19 @@ stub_python_build() {
unstub pyenv-rehash
}
@test "install resolves a prefix" {
stub_python_build 'echo python-build "$@"'
stub pyenv-latest '-q -k 3.4 : echo 3.4.2'
pyenv-latest || true # pass through the stub entry added by stub_python_build
run pyenv-install 3.4
assert_success "python-build 3.4.2 ${PYENV_ROOT}/versions/3.4.2"
unstub python-build
unstub pyenv-hooks
unstub pyenv-rehash
}
@test "install pyenv local version by default" {
stub_python_build 'echo python-build "$1"'
stub pyenv-local 'echo 3.4.2'
@@ -195,12 +209,28 @@ OUT
unstub pyenv-help
}
@test "too many arguments for pyenv-uninstall" {
stub pyenv-help 'uninstall : true'
@test "more than one argument for pyenv-uninstall" {
mkdir -p "${PYENV_ROOT}/versions/3.4.1"
mkdir -p "${PYENV_ROOT}/versions/3.4.2"
run pyenv-uninstall -f 3.4.1 3.4.2
run pyenv-uninstall 3.4.1 3.4.2
assert_success
refute [ -d "${PYENV_ROOT}/versions/3.4.1" ]
refute [ -d "${PYENV_ROOT}/versions/3.4.2" ]
}
@test "invalid arguments for pyenv-uninstall" {
mkdir -p "${PYENV_ROOT}/versions/3.10.3"
mkdir -p "${PYENV_ROOT}/versions/3.10.4"
run pyenv-uninstall -f 3.10.3 --invalid-option 3.10.4
assert_failure
unstub pyenv-help
assert [ -d "${PYENV_ROOT}/versions/3.10.3" ]
assert [ -d "${PYENV_ROOT}/versions/3.10.4" ]
rmdir "${PYENV_ROOT}/versions/3.10.3"
rmdir "${PYENV_ROOT}/versions/3.10.4"
}
@test "show help for pyenv-uninstall" {

View File

@@ -111,8 +111,10 @@ assert_failure() {
assert_equal() {
if [ "$1" != "$2" ]; then
{ echo "expected: $1"
echo "actual: $2"
{ echo "expected:"
echo "$1"
echo "actual:"
echo "$2"
} | flunk
fi
}
@@ -137,3 +139,29 @@ assert_output_contains() {
} | flunk
}
}
# Output a modified PATH that ensures that the given executable is not present,
# but in which system utils necessary for pyenv operation are still available.
path_without() {
local path=":${PATH}:"
for exe; do
local found alt util
for found in $(PATH="$path" type -aP "$exe"); do
found="${found%/*}"
if [ "$found" != "${PYENV_ROOT}/shims" ]; then
alt="${PYENV_TEST_DIR}/$(echo "${found#/}" | tr '/' '-')"
mkdir -p "$alt"
for util in bash head cut readlink greadlink; do
if [ -x "${found}/$util" ]; then
ln -s "${found}/$util" "${alt}/$util"
fi
done
path="${path/:${found}:/:${alt}:}"
fi
done
done
path="${path#:}"
path="${path%:}"
echo "$path"
}

View File

@@ -1,7 +1,13 @@
DEFINITION_PREFIX="${DEFINITION%%:*}"
DEFINITION_TYPE="${DEFINITION_PREFIX%%-*}" # TODO: support non-CPython versions
if [[ "${DEFINITION}" != "${DEFINITION_PREFIX}" ]]; then
DEFINITION_CANDIDATES=($(python-build --definitions | grep -F "${DEFINITION_PREFIX}" | grep "^${DEFINITION_TYPE}" | sed -e '/-dev$/d' -e '/-src$/d' | sort -t. -k1,1r -k 2,2nr -k 3,3nr || true))
DEFINITION_CANDIDATES=(\
$(python-build --definitions | \
grep -F "${DEFINITION_PREFIX}" | \
grep "^${DEFINITION_TYPE}" | \
sed -E -e '/-dev$/d' -e '/-src$/d' -e '/(b|rc)[0-9]+$/d' | \
sort -t. -k1,1r -k 2,2nr -k 3,3nr \
|| true))
DEFINITION="${DEFINITION_CANDIDATES}"
VERSION_NAME="${DEFINITION##*/}"
fi

View File

@@ -2,5 +2,6 @@
activate
activate.csh
activate.fish
activate.nu
# gettext (#688)
gettext.sh

View File

@@ -98,7 +98,6 @@ echo "\$PATH"
command -v fish >/dev/null || skip "-- fish not installed"
OLDPATH="$PATH"
export PATH="${BATS_TEST_DIRNAME}/nonexistent:${PYENV_ROOT}/shims:$PATH"
# fish 2 (Ubuntu Bionic) adds spurious messages when setting PATH, messing up the output
run fish <<!
set -x PATH "$PATH"
pyenv init - | source
@@ -108,6 +107,50 @@ echo "\$PATH"
assert_output "${PYENV_ROOT}/shims:${BATS_TEST_DIRNAME}/nonexistent:${OLDPATH//${PYENV_ROOT}\/shims:/}"
}
@test "adds shims to PATH with --no-push-path if they're not on PATH" {
export PATH="${BATS_TEST_DIRNAME}/../libexec:/usr/bin:/bin:/usr/local/bin"
run bash -e <<!
eval "\$(pyenv-init - --no-push-path)"
echo "\$PATH"
!
assert_success
assert_output "${PYENV_ROOT}/shims:${PATH}"
}
@test "adds shims to PATH with --no-push-path if they're not on PATH (fish)" {
command -v fish >/dev/null || skip "-- fish not installed"
export PATH="${BATS_TEST_DIRNAME}/../libexec:/usr/bin:/bin:/usr/local/bin"
run fish <<!
set -x PATH "$PATH"
pyenv-init - --no-push-path| source
echo "\$PATH"
!
assert_success
assert_output "${PYENV_ROOT}/shims:${PATH}"
}
@test "doesn't change PATH with --no-push-path if shims are already on PATH" {
export PATH="${BATS_TEST_DIRNAME}/../libexec:${PYENV_ROOT}/shims:/usr/bin:/bin:/usr/local/bin"
run bash -e <<!
eval "\$(pyenv-init - --no-push-path)"
echo "\$PATH"
!
assert_success
assert_output "${PATH}"
}
@test "doesn't change PATH with --no-push-path if shims are already on PATH (fish)" {
command -v fish >/dev/null || skip "-- fish not installed"
export PATH="${BATS_TEST_DIRNAME}/../libexec:/usr/bin:${PYENV_ROOT}/shims:/bin:/usr/local/bin"
run fish <<!
set -x PATH "$PATH"
pyenv-init - --no-push-path| source
echo "\$PATH"
!
assert_success
assert_output "${PATH}"
}
@test "outputs sh-compatible syntax" {
run pyenv-init - bash
assert_success

95
test/latest.bats Normal file
View File

@@ -0,0 +1,95 @@
#!/usr/bin/env bats
load test_helper
setup() {
export PATH="${PYENV_TEST_DIR}/bin:$PATH"
}
create_executable() {
local name="$1"
local bin="${PYENV_TEST_DIR}/bin"
mkdir -p "$bin"
sed -Ee '1s/^ +//' > "${bin}/$name"
chmod +x "${bin}/$name"
}
@test "read from installed" {
create_executable pyenv-versions <<!
#!$BASH
echo 4.5.6
!
run pyenv-latest 4
assert_success
assert_output <<!
4.5.6
!
}
@test "read from known" {
create_executable python-build <<!
#!$BASH
echo 4.5.6
!
run pyenv-latest -k 4
assert_success
assert_output <<!
4.5.6
!
}
@test "installed version not found" {
create_executable pyenv-versions <<!
#!$BASH
echo 3.5.6
echo 3.10.8
!
run pyenv-latest 3.8
assert_failure
assert_output <<!
pyenv: no installed versions match the prefix \`3.8'
!
}
@test "known version not found" {
create_executable python-build <<!
#!$BASH
echo 3.5.6
echo 3.10.8
!
run pyenv-latest -k 3.8
assert_failure
assert_output <<!
pyenv: no known versions match the prefix \`3.8'
!
}
@test "complete name resolves to itself" {
create_executable pyenv-versions <<!
#!$BASH
echo foo
echo foo.bar
!
run pyenv-latest foo
assert_success
assert_output <<!
foo
!
}
@test "sort CPython" {
create_executable pyenv-versions <<!
#!$BASH
echo 2.7.18
echo 3.5.6
echo 3.10.8
echo 3.10.6
!
run pyenv-latest 3
assert_success
assert_output <<!
3.10.8
!
}

View File

@@ -83,14 +83,36 @@ IN
assert_success "3.9.3:3.8.9:2.7.16"
}
@test "skips relative path traversal" {
@test "skips \`..' relative path traversal" {
echo '..' > my-version
run pyenv-version-file-read my-version
assert_failure "pyenv: invalid version \`..' ignored in \`my-version'"
}
@test "skips glob path traversal" {
cat > my-version <<IN
../*
3.9.3
3.8.9
..
./*
2.7.16
IN
run pyenv-version-file-read my-version
assert_success "3.9.3:3.8.9:2.7.16"
assert_success <<OUT
pyenv: invalid version \`../\*' ignored in \`my-version'
3.9.3
OUT
}
@test "allows relative paths that exist and stay within versions" {
venv=3.10.3/envs/../test
mkdir -p "${PYENV_ROOT}/versions/${venv}"
echo -n "${venv}" > my-version
run pyenv-version-file-read my-version
assert_success "${venv}"
}
@test "skips relative paths that lead outside of versions" {
venv=../3.10.3/envs/test
mkdir -p "${PYENV_ROOT}/versions/${venv}"
echo -n "${venv}" > my-version
run pyenv-version-file-read my-version
assert_failure
}

View File

@@ -113,3 +113,10 @@ OUT
assert_success
assert_output "2.7.11"
}
@test "falls back to pyenv-latest" {
create_version "2.7.11"
PYENV_VERSION="2.7" run pyenv-version-name
assert_success
assert_output "2.7.11"
}