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

Compare commits

...

39 Commits

Author SHA1 Message Date
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
47 changed files with 1503 additions and 188 deletions

View File

@@ -6,10 +6,10 @@ jobs:
fail-fast: false
matrix:
python-version:
- 3.7.13
- 3.8.13
- 3.9.13
- 3.10.6
- "3.7"
- "3.8"
- "3.9"
- "3.10"
runs-on: macos-11
steps:
- uses: actions/checkout@v2

View File

@@ -6,10 +6,10 @@ jobs:
fail-fast: false
matrix:
python-version:
- 3.7.13
- 3.8.13
- 3.9.13
- 3.10.6
- "3.7"
- "3.8"
- "3.9"
- "3.10"
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2

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,5 +1,34 @@
## Version History
## 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)

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
@@ -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.

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)
@@ -324,14 +327,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 +386,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 +402,25 @@ please visit the wiki page about
[Common Build Problems](https://github.com/pyenv/pyenv/wiki/Common-build-problems).
#### Prefix auto-resolution
Pyenv automatically resolves full prefixes to the latest version in the corresponding version line.
E.g. to install the latest 3.10 release:
```sh
pyenv install 3.10
```
The same happens whenever Pyenv selects a version to use.
Installation selects the latest version known to Pyenv
while switching -- the latest installed version.
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 on the resolution process.
#### Python versions with extended support
For the following Python releases, Pyenv applies user-provided patches that add support for some newer environments.
@@ -397,7 +428,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
@@ -452,12 +483,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.4"
version="2.3.6"
git_revision=""
if cd "${BASH_SOURCE%/*}" 2>/dev/null && git remote -v 2>/dev/null | grep -q pyenv; then

View File

@@ -155,7 +155,11 @@ function print_path() {
# (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 '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[*]}"'\'')"'
echo 'export PATH="'"${PYENV_ROOT}"'/shims:${PATH}"'
;;
esac

74
libexec/pyenv-latest Executable file
View File

@@ -0,0 +1,74 @@
#!/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
# 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

@@ -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

@@ -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

@@ -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
@@ -709,7 +714,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 +779,7 @@ build_package_standard_build() {
else
use_homebrew_zlib || true
fi
use_dsymutil || true
fi
( if [ "${CFLAGS+defined}" ] || [ "${!PACKAGE_CFLAGS+defined}" ]; then
@@ -932,10 +938,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 +1091,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 +1105,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 +1348,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 +1370,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 +1414,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 +1455,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 +1555,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"
@@ -1549,14 +1575,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 +1620,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 +1636,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 +1650,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 +1676,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 +2041,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

@@ -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.0rc1" "https://www.python.org/ftp/python/3.11.0/Python-3.11.0rc1.tar.xz#53a5377c37a8a2c6da075b14eb9d63374579f7f3c718fa20f0a1fbb0e94a922b" standard verify_py311 copy_python_gdb ensurepip
else
install_package "Python-3.11.0rc1" "https://www.python.org/ftp/python/3.11.0/Python-3.11.0rc1.tgz#456f32a8d66e7cae226478a74c3ebb358bae09eba0b8537f47d7b2790f65a1f0" 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.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.12.0a1" "https://www.python.org/ftp/python/3.12.0/Python-3.12.0a1.tar.xz#7be2bd9b1fc9f64b334660581bb645f0eae0b344c80130f1eb22983a1c292f43" standard verify_py312 copy_python_gdb ensurepip
else
install_package "Python-3.12.0a1" "https://www.python.org/ftp/python/3.12.0/Python-3.12.0a1.tgz#db4dd2315715e11250175f5dc06fa9d32d4a9fed4db7b6774d4be72d7b94b7e3" 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.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.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,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

@@ -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,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'

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"

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'

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

80
test/latest.bats Normal file
View File

@@ -0,0 +1,80 @@
#!/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 "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

@@ -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"
}