mirror of
https://github.com/pyenv/pyenv.git
synced 2025-11-09 03:53:48 -05:00
Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2b22145670 | ||
|
|
7c1c180551 | ||
|
|
a648682ed6 | ||
|
|
47b0ce77c0 | ||
|
|
fdabd14c2b | ||
|
|
e52ad61389 | ||
|
|
2e5983b004 | ||
|
|
27b5f62dfb | ||
|
|
7c1e3a710c | ||
|
|
13f273188d | ||
|
|
c89a69a6ed | ||
|
|
a8afc61146 | ||
|
|
e4a0c12b1b | ||
|
|
afeb971fa2 | ||
|
|
965421d5d4 | ||
|
|
ae22c69505 | ||
|
|
37a6070855 | ||
|
|
1ae5596bfa | ||
|
|
ff9d3ca69e | ||
|
|
d98d3f5055 | ||
|
|
f5cbba0636 | ||
|
|
16f7ea03e8 | ||
|
|
22fa683571 | ||
|
|
0eba0a5bd5 | ||
|
|
0990e7843d | ||
|
|
aee9c82c29 | ||
|
|
fdaeaf1f97 | ||
|
|
207f33fc5e |
12
.github/workflows/macos_build.yml
vendored
12
.github/workflows/macos_build.yml
vendored
@@ -6,11 +6,11 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
python-version:
|
python-version:
|
||||||
- 3.7.10
|
- 3.7.13
|
||||||
- 3.8.10
|
- 3.8.13
|
||||||
- 3.9.5
|
- 3.9.13
|
||||||
- 3.10.0
|
- 3.10.6
|
||||||
runs-on: macos-10.15
|
runs-on: macos-11
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
# Normally, we would use the superbly maintained...
|
# Normally, we would use the superbly maintained...
|
||||||
@@ -27,7 +27,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
echo $PYENV_ROOT
|
echo $PYENV_ROOT
|
||||||
echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH
|
echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH
|
||||||
bin/pyenv install ${{ matrix.python-version }}
|
bin/pyenv install -v ${{ matrix.python-version }}
|
||||||
bin/pyenv global ${{ matrix.python-version }}
|
bin/pyenv global ${{ matrix.python-version }}
|
||||||
bin/pyenv rehash
|
bin/pyenv rehash
|
||||||
- run: python --version
|
- run: python --version
|
||||||
|
|||||||
85
.github/workflows/modified_scripts_build.yml
vendored
85
.github/workflows/modified_scripts_build.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
|||||||
run: >
|
run: >
|
||||||
versions=$(git diff "origin/$GITHUB_BASE_REF" --name-only -z
|
versions=$(git diff "origin/$GITHUB_BASE_REF" --name-only -z
|
||||||
| perl -ne 'BEGIN {$\="\n";$/="\0";} chomp;
|
| 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; }' \
|
{ print $1.$2; }' \
|
||||||
| sort -u);
|
| sort -u);
|
||||||
echo -e "versions<<!\\n$versions\\n!" >> $GITHUB_ENV
|
echo -e "versions<<!\\n$versions\\n!" >> $GITHUB_ENV
|
||||||
@@ -27,7 +27,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
python-version: ${{fromJson(needs.discover_modified_scripts.outputs.versions)}}
|
python-version: ${{fromJson(needs.discover_modified_scripts.outputs.versions)}}
|
||||||
os: ["macos-10.15", "macos-11"]
|
os: ["macos-11", "macos-12"]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
@@ -38,22 +38,33 @@ jobs:
|
|||||||
echo "PYENV_ROOT=$PYENV_ROOT" >> $GITHUB_ENV
|
echo "PYENV_ROOT=$PYENV_ROOT" >> $GITHUB_ENV
|
||||||
echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH
|
echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH
|
||||||
- run: |
|
- run: |
|
||||||
pyenv install ${{ matrix.python-version }}
|
pyenv install -v ${{ matrix.python-version }}
|
||||||
pyenv global ${{ matrix.python-version }}
|
pyenv global ${{ matrix.python-version }}
|
||||||
- run: |
|
# Micropython doesn't support --version
|
||||||
python --version
|
- run: >
|
||||||
python -m pip --version
|
if [[ "${{ matrix.python-version }}" == "micropython-"* ]]; then
|
||||||
- shell: python # Prove that actual Python == expected Python
|
python -c 'import sys; print(sys.version)'
|
||||||
env:
|
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 }}
|
EXPECTED_PYTHON: ${{ matrix.python-version }}
|
||||||
run: |
|
run: |
|
||||||
import os, sys, os.path
|
if [[ "${{ matrix.python-version }}" == "micropython-"* ]]; then
|
||||||
correct_dir = os.path.join(
|
[[ $(pyenv which python) == "${{ env.PYENV_ROOT }}/versions/${{ matrix.python-version }}/bin/python" ]] || exit 1
|
||||||
os.environ['PYENV_ROOT'],
|
python -c 'import sys; assert sys.implementation.name == "micropython"'
|
||||||
'versions',
|
else
|
||||||
os.environ['EXPECTED_PYTHON'],
|
python -c 'if True:
|
||||||
'bin')
|
import os, sys, os.path
|
||||||
assert os.path.dirname(sys.executable) == correct_dir
|
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
|
# bundled executables in some Anaconda releases cause the post-run step to hang in MacOS
|
||||||
- run: |
|
- run: |
|
||||||
pyenv global system
|
pyenv global system
|
||||||
@@ -66,32 +77,44 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
python-version: ${{fromJson(needs.discover_modified_scripts.outputs.versions)}}
|
python-version: ${{fromJson(needs.discover_modified_scripts.outputs.versions)}}
|
||||||
os: ["ubuntu-18.04", "ubuntu-20.04"]
|
os: ["ubuntu-20.04", "ubuntu-22.04"]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- run: |
|
- 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 \
|
libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev \
|
||||||
wget curl llvm libncurses5-dev libncursesw5-dev \
|
curl llvm libncurses5-dev libncursesw5-dev \
|
||||||
xz-utils tk-dev libffi-dev liblzma-dev python-openssl git
|
xz-utils tk-dev libffi-dev liblzma-dev
|
||||||
- run: |
|
- run: |
|
||||||
export PYENV_ROOT="$GITHUB_WORKSPACE"
|
export PYENV_ROOT="$GITHUB_WORKSPACE"
|
||||||
echo "PYENV_ROOT=$PYENV_ROOT" >> $GITHUB_ENV
|
echo "PYENV_ROOT=$PYENV_ROOT" >> $GITHUB_ENV
|
||||||
echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH
|
echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH
|
||||||
- run: |
|
- run: |
|
||||||
pyenv install ${{ matrix.python-version }}
|
pyenv install -v ${{ matrix.python-version }}
|
||||||
pyenv global ${{ matrix.python-version }}
|
pyenv global ${{ matrix.python-version }}
|
||||||
- run: python --version
|
# Micropython doesn't support --version
|
||||||
- run: python -m pip --version
|
- run: >
|
||||||
- shell: python # Prove that actual Python == expected Python
|
if [[ "${{ matrix.python-version }}" == "micropython-"* ]]; then
|
||||||
env:
|
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 }}
|
EXPECTED_PYTHON: ${{ matrix.python-version }}
|
||||||
run: |
|
run: |
|
||||||
import os, sys, os.path
|
if [[ "${{ matrix.python-version }}" == "micropython-"* ]]; then
|
||||||
correct_dir = os.path.join(
|
[[ $(pyenv which python) == "${{ env.PYENV_ROOT }}/versions/${{ matrix.python-version }}/bin/python" ]] || exit 1
|
||||||
os.environ['PYENV_ROOT'],
|
python -c 'import sys; assert sys.implementation.name == "micropython"'
|
||||||
'versions',
|
else
|
||||||
os.environ['EXPECTED_PYTHON'],
|
python -c 'if True:
|
||||||
'bin')
|
import os, sys, os.path
|
||||||
assert os.path.dirname(sys.executable) == correct_dir
|
correct_dir = os.path.join(
|
||||||
|
os.environ["PYENV_ROOT"],
|
||||||
|
"versions",
|
||||||
|
os.environ["EXPECTED_PYTHON"],
|
||||||
|
"bin")
|
||||||
|
assert os.path.dirname(sys.executable) == correct_dir'
|
||||||
|
fi
|
||||||
|
|||||||
4
.github/workflows/pyenv_tests.yml
vendored
4
.github/workflows/pyenv_tests.yml
vendored
@@ -6,10 +6,10 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os:
|
os:
|
||||||
|
- ubuntu-22.04
|
||||||
- ubuntu-20.04
|
- ubuntu-20.04
|
||||||
- ubuntu-18.04
|
- macos-12
|
||||||
- macos-11
|
- macos-11
|
||||||
- macos-10.15
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|||||||
18
.github/workflows/ubuntu_build.yml
vendored
18
.github/workflows/ubuntu_build.yml
vendored
@@ -6,11 +6,11 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
python-version:
|
python-version:
|
||||||
- 3.7.10
|
- 3.7.13
|
||||||
- 3.8.10
|
- 3.8.13
|
||||||
- 3.9.5
|
- 3.9.13
|
||||||
- 3.10.0
|
- 3.10.6
|
||||||
runs-on: Ubuntu-20.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
# Normally, we would use the superbly maintained...
|
# Normally, we would use the superbly maintained...
|
||||||
@@ -19,9 +19,9 @@ jobs:
|
|||||||
# python-version: ${{ matrix.python-version }}
|
# python-version: ${{ matrix.python-version }}
|
||||||
# ... but in the repo, we want to test pyenv builds on Ubuntu
|
# ... but in the repo, we want to test pyenv builds on Ubuntu
|
||||||
- run: |
|
- run: |
|
||||||
sudo apt-get install -y build-essential libssl-dev zlib1g-dev libbz2-dev \
|
sudo apt-get install -yq make build-essential libssl-dev zlib1g-dev \
|
||||||
libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \
|
libbz2-dev libreadline-dev libsqlite3-dev curl \
|
||||||
xz-utils tk-dev libffi-dev liblzma-dev python-openssl git
|
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
|
||||||
# https://github.com/pyenv/pyenv#installation
|
# https://github.com/pyenv/pyenv#installation
|
||||||
- run: pwd
|
- run: pwd
|
||||||
- env:
|
- env:
|
||||||
@@ -29,7 +29,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
echo $PYENV_ROOT
|
echo $PYENV_ROOT
|
||||||
echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH
|
echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH
|
||||||
bin/pyenv install ${{ matrix.python-version }}
|
bin/pyenv install -v ${{ matrix.python-version }}
|
||||||
bin/pyenv global ${{ matrix.python-version }}
|
bin/pyenv global ${{ matrix.python-version }}
|
||||||
bin/pyenv rehash
|
bin/pyenv rehash
|
||||||
- run: python --version
|
- run: python --version
|
||||||
|
|||||||
21
CHANGELOG.md
21
CHANGELOG.md
@@ -1,5 +1,26 @@
|
|||||||
## Version History
|
## Version History
|
||||||
|
|
||||||
|
## 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
|
||||||
|
|
||||||
|
* Use version sort in `pyenv versions` (#2405)
|
||||||
|
* Add CPython 3.11.0b4 (#2411)
|
||||||
|
* Python-build: Replace deprecated git protocol use with https in docs (#2413)
|
||||||
|
* Fix relative path traversal due to using version string in path (#2412)
|
||||||
|
* Allow pypy2 and pypy3 patching (#2421, #2419)
|
||||||
|
* Add CPython 3.11.0b5 (#2420)
|
||||||
|
* Add GraalPython 22.2.0 (#2425)
|
||||||
|
* Add CPython 3.10.6 (#2428)
|
||||||
|
|
||||||
## Release 2.3.2
|
## Release 2.3.2
|
||||||
|
|
||||||
* Add CPython 3.11.0b2 (#2380)
|
* Add CPython 3.11.0b2 (#2380)
|
||||||
|
|||||||
@@ -238,9 +238,9 @@ To install the latest major release for Python 3 try:
|
|||||||
|
|
||||||
## `pyenv uninstall`
|
## `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
|
-f Attempt to remove the specified version without prompting
|
||||||
for confirmation. If the version does not exist, do not
|
for confirmation. If the version does not exist, do not
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
General guidance
|
General guidance
|
||||||
================
|
================
|
||||||
|
|
||||||
* The usual principes of respecting existing conventions and making sure that your changes
|
* 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.
|
are in line with the overall product design apply when contributing code to Pyenv.
|
||||||
|
|
||||||
* We are limited to Bash 3.2 features
|
* We are limited to Bash 3.2 features
|
||||||
@@ -9,6 +9,9 @@ General guidance
|
|||||||
That's because that's the version shipped with MacOS.
|
That's because that's the version shipped with MacOS.
|
||||||
(They didn't upgrade past it and switched to Zsh because later versions
|
(They didn't upgrade past it and switched to Zsh because later versions
|
||||||
are covered by GPLv3 which has additional restrictions unacceptable for Apple.)
|
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
|
* Be extra careful when submitting logic specific for the Apple Silicon platform
|
||||||
|
|
||||||
|
|||||||
@@ -288,7 +288,7 @@ See [Advanced configuration](#advanced-configuration) for details and more confi
|
|||||||
configuration commands to both `.bashrc` (for interactive shells)
|
configuration commands to both `.bashrc` (for interactive shells)
|
||||||
and the profile file that Bash would use (for login 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
|
~~~ bash
|
||||||
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
|
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
|
||||||
@@ -432,7 +432,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
|
As time goes on, you will accumulate Python versions in your
|
||||||
`$(pyenv root)/versions` directory.
|
`$(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
|
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
|
to remove. You can find the directory of a particular Python version
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
set -e
|
set -e
|
||||||
[ -n "$PYENV_DEBUG" ] && set -x
|
[ -n "$PYENV_DEBUG" ] && set -x
|
||||||
|
|
||||||
version="2.3.2"
|
version="2.3.4"
|
||||||
git_revision=""
|
git_revision=""
|
||||||
|
|
||||||
if cd "${BASH_SOURCE%/*}" 2>/dev/null && git remote -v 2>/dev/null | grep -q pyenv; then
|
if cd "${BASH_SOURCE%/*}" 2>/dev/null && git remote -v 2>/dev/null | grep -q pyenv; then
|
||||||
|
|||||||
@@ -5,15 +5,37 @@ set -e
|
|||||||
|
|
||||||
VERSION_FILE="$1"
|
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
|
if [ -s "$VERSION_FILE" ]; then
|
||||||
# Read the first non-whitespace word from the specified version file.
|
# 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.
|
# Be careful not to load it whole in case there's something crazy in it.
|
||||||
IFS="${IFS}"$'\r'
|
IFS="$IFS"$'\r'
|
||||||
sep=
|
sep=
|
||||||
while read -n 1024 -r version _ || [[ $version ]]; do
|
while read -n 1024 -r version _ || [[ $version ]]; do
|
||||||
[[ -z $version || $version == \#* ]] && continue
|
if [[ -z "$version" || "$version" == \#* ]]; then
|
||||||
printf "%s%s" "$sep" "$version"
|
# Skip empty lines and comments
|
||||||
sep=:
|
continue
|
||||||
|
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"
|
||||||
|
sep=:
|
||||||
done <"$VERSION_FILE"
|
done <"$VERSION_FILE"
|
||||||
[[ $sep ]] && { echo; exit; }
|
[[ $sep ]] && { echo; exit; }
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -123,7 +123,19 @@ if [ -n "$include_system" ] && \
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
shopt -s dotglob nullglob
|
shopt -s dotglob nullglob
|
||||||
for path in "$versions_dir"/*; do
|
versions_dir_entries=("$versions_dir"/*)
|
||||||
|
if sort --version-sort </dev/null >/dev/null 2>&1; then
|
||||||
|
# system sort supports version sorting
|
||||||
|
OLDIFS="$IFS"
|
||||||
|
IFS=$'\n'
|
||||||
|
versions_dir_entries=($(
|
||||||
|
printf "%s\n" "${versions_dir_entries[@]}" |
|
||||||
|
sort --version-sort
|
||||||
|
))
|
||||||
|
IFS="$OLDIFS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
for path in "${versions_dir_entries[@]}"; do
|
||||||
if [ -d "$path" ]; then
|
if [ -d "$path" ]; then
|
||||||
if [ -n "$skip_aliases" ] && [ -L "$path" ]; then
|
if [ -n "$skip_aliases" ] && [ -L "$path" ]; then
|
||||||
target="$(realpath "$path")"
|
target="$(realpath "$path")"
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ Set or show the shell\-specific Python version
|
|||||||
List existing pyenv shims
|
List existing pyenv shims
|
||||||
.TP
|
.TP
|
||||||
.B uninstall
|
.B uninstall
|
||||||
Uninstall a specific Python version
|
Uninstall Python versions
|
||||||
.TP
|
.TP
|
||||||
.B version
|
.B version
|
||||||
Show the current Python version(s) and its origin
|
Show the current Python version(s) and its origin
|
||||||
@@ -452,10 +452,10 @@ $ pyenv versions
|
|||||||
.fi
|
.fi
|
||||||
.IP "" 0
|
.IP "" 0
|
||||||
.SS "pyenv uninstall"
|
.SS "pyenv uninstall"
|
||||||
Uninstall a specific Python version\.
|
Uninstall Python versions\.
|
||||||
.IP "" 4
|
.IP "" 4
|
||||||
.nf
|
.nf
|
||||||
Usage: pyenv uninstall [\-f|\-\-force] <version>
|
Usage: pyenv uninstall [\-f|\-\-force] <version> ...
|
||||||
|
|
||||||
\-f Attempt to remove the specified version without prompting
|
\-f Attempt to remove the specified version without prompting
|
||||||
for confirmation\. If the version does not exist, do not
|
for confirmation\. If the version does not exist, do not
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ Installing python-build as a standalone program will give you access to the
|
|||||||
`python-build` command for precise control over Python version installation. If you
|
`python-build` command for precise control over Python version installation. If you
|
||||||
have pyenv installed, you will also be able to use the `pyenv install` command.
|
have pyenv installed, you will also be able to use the `pyenv install` command.
|
||||||
|
|
||||||
git clone git://github.com/pyenv/pyenv.git
|
git clone https://github.com/pyenv/pyenv.git
|
||||||
cd pyenv/plugins/python-build
|
cd pyenv/plugins/python-build
|
||||||
./install.sh
|
./install.sh
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#!/usr/bin/env bash
|
#!/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
|
# -f Attempt to remove the specified version without prompting
|
||||||
# for confirmation. If the version does not exist, do not
|
# for confirmation. If the version does not exist, do not
|
||||||
@@ -33,14 +33,17 @@ if [ "$1" = "-f" ] || [ "$1" = "--force" ]; then
|
|||||||
shift
|
shift
|
||||||
fi
|
fi
|
||||||
|
|
||||||
[ "$#" -eq 1 ] || usage 1 >&2
|
[ "$#" -gt 0 ] || usage 1 >&2
|
||||||
|
|
||||||
DEFINITION="$1"
|
versions=("$@")
|
||||||
case "$DEFINITION" in
|
|
||||||
"" | -* )
|
for version in "${versions[@]}"; do
|
||||||
usage 1 >&2
|
case "$version" in
|
||||||
;;
|
"" | -* )
|
||||||
esac
|
usage 1 >&2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
declare -a before_hooks after_hooks
|
declare -a before_hooks after_hooks
|
||||||
|
|
||||||
@@ -59,29 +62,36 @@ IFS=$'\n' scripts=(`pyenv-hooks uninstall`)
|
|||||||
IFS="$OLDIFS"
|
IFS="$OLDIFS"
|
||||||
for script in "${scripts[@]}"; do source "$script"; done
|
for script in "${scripts[@]}"; do source "$script"; done
|
||||||
|
|
||||||
|
uninstall-python() {
|
||||||
|
local DEFINITION="$1"
|
||||||
|
|
||||||
VERSION_NAME="${DEFINITION##*/}"
|
local VERSION_NAME="${DEFINITION##*/}"
|
||||||
PREFIX="${PYENV_ROOT}/versions/${VERSION_NAME}"
|
local PREFIX="${PYENV_ROOT}/versions/${VERSION_NAME}"
|
||||||
|
|
||||||
if [ -z "$FORCE" ]; then
|
if [ -z "$FORCE" ]; then
|
||||||
if [ ! -d "$PREFIX" ]; then
|
if [ ! -d "$PREFIX" ]; then
|
||||||
echo "pyenv: version \`$VERSION_NAME' not installed" >&2
|
echo "pyenv: version \`$VERSION_NAME' not installed" >&2
|
||||||
exit 1
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
read -p "pyenv: remove $PREFIX? [y|N] "
|
||||||
|
case "$REPLY" in
|
||||||
|
y | Y | yes | YES ) ;;
|
||||||
|
* ) exit 1 ;;
|
||||||
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
read -p "pyenv: remove $PREFIX? [y|N] "
|
for hook in "${before_hooks[@]}"; do eval "$hook"; done
|
||||||
case "$REPLY" in
|
|
||||||
y | Y | yes | YES ) ;;
|
|
||||||
* ) exit 1 ;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
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
|
for hook in "${after_hooks[@]}"; do eval "$hook"; done
|
||||||
rm -rf "$PREFIX"
|
}
|
||||||
pyenv-rehash
|
|
||||||
echo "pyenv: $VERSION_NAME uninstalled"
|
|
||||||
fi
|
|
||||||
|
|
||||||
for hook in "${after_hooks[@]}"; do eval "$hook"; done
|
for version in "${versions[@]}"; do
|
||||||
|
uninstall-python "$version"
|
||||||
|
done
|
||||||
|
|||||||
@@ -899,7 +899,7 @@ build_package_micropython() {
|
|||||||
"$MAKE" $MAKE_OPTS
|
"$MAKE" $MAKE_OPTS
|
||||||
cd ../ports/unix
|
cd ../ports/unix
|
||||||
"$MAKE" $MAKE_OPTS axtls
|
"$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}"
|
"$MAKE" install $MAKE_INSTALL_OPTS PREFIX="${PREFIX_PATH}"
|
||||||
ln -fs micropython "${PREFIX_PATH}/bin/python"
|
ln -fs micropython "${PREFIX_PATH}/bin/python"
|
||||||
mkdir -p "${PREFIX_PATH}/lib/micropython"
|
mkdir -p "${PREFIX_PATH}/lib/micropython"
|
||||||
@@ -1637,10 +1637,19 @@ build_package_auto_tcltk() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# extglob must be set at parse time, not at 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() {
|
apply_python_patch() {
|
||||||
local patchfile
|
local patchfile
|
||||||
|
# needed at runtime
|
||||||
|
shopt -s extglob
|
||||||
case "$1" in
|
case "$1" in
|
||||||
Python-* | jython-* | pypy-* | stackless-* )
|
Python-* | jython-* | pypy-* | pypy[0-9].+([0-9])-* | stackless-* )
|
||||||
patchfile="$(mktemp "${TMP}/python-patch.XXXXXX")"
|
patchfile="$(mktemp "${TMP}/python-patch.XXXXXX")"
|
||||||
cat "${2:--}" >"$patchfile"
|
cat "${2:--}" >"$patchfile"
|
||||||
|
|
||||||
@@ -1649,7 +1658,9 @@ apply_python_patch() {
|
|||||||
patch -p$striplevel --force -i "$patchfile"
|
patch -p$striplevel --force -i "$patchfile"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
shopt -u extglob
|
||||||
}
|
}
|
||||||
|
shopt -u extglob
|
||||||
|
|
||||||
build_package_symlink_version_suffix() {
|
build_package_symlink_version_suffix() {
|
||||||
if [[ "$CONFIGURE_OPTS $PYTHON_CONFIGURE_OPTS" == *"--enable-framework"* ]]; then
|
if [[ "$CONFIGURE_OPTS $PYTHON_CONFIGURE_OPTS" == *"--enable-framework"* ]]; then
|
||||||
|
|||||||
9
plugins/python-build/share/python-build/3.10.6
Normal file
9
plugins/python-build/share/python-build/3.10.6
Normal 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.6" "https://www.python.org/ftp/python/3.10.6/Python-3.10.6.tar.xz#f795ff87d11d4b0c7c33bc8851b0c28648d8a4583aa2100a98c22b4326b6d3f3" standard verify_py310 copy_python_gdb ensurepip
|
||||||
|
else
|
||||||
|
install_package "Python-3.10.6" "https://www.python.org/ftp/python/3.10.6/Python-3.10.6.tgz#848cb06a5caa85da5c45bd7a9221bb821e33fc2bdcba088c127c58fad44e6343" standard verify_py310 copy_python_gdb ensurepip
|
||||||
|
fi
|
||||||
@@ -3,7 +3,7 @@ export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
|
|||||||
install_package "openssl-1.1.1n" "https://www.openssl.org/source/openssl-1.1.1n.tar.gz#40dceb51a4f6a5275bde0e6bf20ef4b91bfc32ed57c0552e2e8e15463372b17a" mac_openssl --if has_broken_mac_openssl
|
install_package "openssl-1.1.1n" "https://www.openssl.org/source/openssl-1.1.1n.tar.gz#40dceb51a4f6a5275bde0e6bf20ef4b91bfc32ed57c0552e2e8e15463372b17a" mac_openssl --if has_broken_mac_openssl
|
||||||
install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline
|
install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline
|
||||||
if has_tar_xz_support; then
|
if has_tar_xz_support; then
|
||||||
install_package "Python-3.11.0b3" "https://www.python.org/ftp/python/3.11.0/Python-3.11.0b3.tar.xz#c9b99f5315ea30f8e9fcbce6807a3739e875480d29124e6d9940f6fabcb7c902" standard verify_py311 copy_python_gdb ensurepip
|
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
|
else
|
||||||
install_package "Python-3.11.0b3" "https://www.python.org/ftp/python/3.11.0/Python-3.11.0b3.tgz#f52b738043251c88e3d6bb86e30cbf0e1098470a06b9d49feb31f145af5e8149" standard verify_py311 copy_python_gdb ensurepip
|
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
|
fi
|
||||||
31
plugins/python-build/share/python-build/cinder-3.8-dev
Normal file
31
plugins/python-build/share/python-build/cinder-3.8-dev
Normal 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
|
||||||
48
plugins/python-build/share/python-build/graalpython-22.2.0
Normal file
48
plugins/python-build/share/python-build/graalpython-22.2.0
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
# 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.2.0'
|
||||||
|
BUILD=''
|
||||||
|
|
||||||
|
case "$(pypy_architecture 2>/dev/null || true)" in
|
||||||
|
"linux64" )
|
||||||
|
graalpython_arch="linux"
|
||||||
|
checksum="75a7e5d7afc158169fd87df9c69c3801aa0293dd727ba09facad6b01e1b6dee5"
|
||||||
|
;;
|
||||||
|
"osx64" )
|
||||||
|
graalpython_arch="macos"
|
||||||
|
checksum="575d78ae2be8d4ce4adbc9c61229b6f1271f557f0f3ec410a494de7b29986dd7"
|
||||||
|
;;
|
||||||
|
* )
|
||||||
|
{ echo
|
||||||
|
colorize 1 "ERROR"
|
||||||
|
echo ": No binary distribution of GraalPython is available for $(pypy_architecture 2>/dev/null || true)."
|
||||||
|
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 "graalpython-${VERSION}${BUILD}" "${urlprefix}/graalpython-${VERSION}-${graalpython_arch}-amd64.tar.gz#${checksum}" "graalpython" ensurepip
|
||||||
4
plugins/python-build/share/python-build/micropython-1.18
Normal file
4
plugins/python-build/share/python-build/micropython-1.18
Normal 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
|
||||||
@@ -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
|
||||||
@@ -1,310 +1,310 @@
|
|||||||
From: Christian Hammond <christian@beanbaginc.com>
|
From: Christian Hammond <christian@beanbaginc.com>
|
||||||
Date: Wed, 15 Dec 2021 23:12:36 -0800
|
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
|
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
|
This ports the following ctypes and libffi pyenv patches for Python
|
||||||
2.7.18 to Python 3.7.12:
|
2.7.18 to Python 3.7.12:
|
||||||
|
|
||||||
* `0004-Use-system-libffi-for-Mac-OS-10.15-and-up.patch`
|
* `0004-Use-system-libffi-for-Mac-OS-10.15-and-up.patch`
|
||||||
* `0005-ctypes-use-the-correct-ABI-for-variadic-functions.patch`
|
* `0005-ctypes-use-the-correct-ABI-for-variadic-functions.patch`
|
||||||
* `0006-ctypes-probe-libffi-for-ffi_closure_alloc-and-ffi_pr.patch`
|
* `0006-ctypes-probe-libffi-for-ffi_closure_alloc-and-ffi_pr.patch`
|
||||||
|
|
||||||
These patches enable use of system libffi (fixing a broken `ctypes`
|
These patches enable use of system libffi (fixing a broken `ctypes`
|
||||||
module on arm64 targets) and enable calling variadic functions on arm64.
|
module on arm64 targets) and enable calling variadic functions on arm64.
|
||||||
They've been combined from patches port from Homebrew to pyenv by Takumi
|
They've been combined from patches port from Homebrew to pyenv by Takumi
|
||||||
Sueda, updated to work on the Python 3.7.12 codebase.
|
Sueda, updated to work on the Python 3.7.12 codebase.
|
||||||
|
|
||||||
The Homebrew patches are themselves backports of changes in Python 3.9
|
The Homebrew patches are themselves backports of changes in Python 3.9
|
||||||
and 3.10. That patch can be found at:
|
and 3.10. That patch can be found at:
|
||||||
|
|
||||||
https://github.com/Homebrew/formula-patches/blob/master/python/3.8.7.patch
|
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
|
diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst
|
||||||
index 715d595b24..7743144978 100644
|
index 715d595b24..7743144978 100644
|
||||||
--- a/Doc/library/ctypes.rst
|
--- a/Doc/library/ctypes.rst
|
||||||
+++ b/Doc/library/ctypes.rst
|
+++ b/Doc/library/ctypes.rst
|
||||||
@@ -1551,6 +1551,13 @@ They are instances of a private class:
|
@@ -1551,6 +1551,13 @@ They are instances of a private class:
|
||||||
value usable as argument (integer, string, ctypes instance). This allows
|
value usable as argument (integer, string, ctypes instance). This allows
|
||||||
defining adapters that can adapt custom objects as function parameters.
|
defining adapters that can adapt custom objects as function parameters.
|
||||||
|
|
||||||
+ .. attribute:: variadic
|
+ .. attribute:: variadic
|
||||||
+
|
+
|
||||||
+ Assign a boolean to specify that the function takes a variable number of
|
+ 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
|
+ arguments. This does not matter on most platforms, but for Apple arm64
|
||||||
+ platforms variadic functions have a different calling convention than
|
+ platforms variadic functions have a different calling convention than
|
||||||
+ normal functions.
|
+ normal functions.
|
||||||
+
|
+
|
||||||
.. attribute:: errcheck
|
.. attribute:: errcheck
|
||||||
|
|
||||||
Assign a Python function or another callable to this attribute. The
|
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
|
diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py
|
||||||
index 4ebd82d3e0..7b73c190b6 100644
|
index 4ebd82d3e0..7b73c190b6 100644
|
||||||
--- a/Lib/test/test_unicode.py
|
--- a/Lib/test/test_unicode.py
|
||||||
+++ b/Lib/test/test_unicode.py
|
+++ b/Lib/test/test_unicode.py
|
||||||
@@ -2458,11 +2458,14 @@ class CAPITest(unittest.TestCase):
|
@@ -2458,11 +2458,14 @@ class CAPITest(unittest.TestCase):
|
||||||
def test_from_format(self):
|
def test_from_format(self):
|
||||||
support.import_module('ctypes')
|
support.import_module('ctypes')
|
||||||
from ctypes import (
|
from ctypes import (
|
||||||
+ c_char_p,
|
+ c_char_p,
|
||||||
pythonapi, py_object, sizeof,
|
pythonapi, py_object, sizeof,
|
||||||
c_int, c_long, c_longlong, c_ssize_t,
|
c_int, c_long, c_longlong, c_ssize_t,
|
||||||
c_uint, c_ulong, c_ulonglong, c_size_t, c_void_p)
|
c_uint, c_ulong, c_ulonglong, c_size_t, c_void_p)
|
||||||
name = "PyUnicode_FromFormat"
|
name = "PyUnicode_FromFormat"
|
||||||
_PyUnicode_FromFormat = getattr(pythonapi, name)
|
_PyUnicode_FromFormat = getattr(pythonapi, name)
|
||||||
+ _PyUnicode_FromFormat.argtypes = (c_char_p,)
|
+ _PyUnicode_FromFormat.argtypes = (c_char_p,)
|
||||||
+ _PyUnicode_FromFormat.variadic = True
|
+ _PyUnicode_FromFormat.variadic = True
|
||||||
_PyUnicode_FromFormat.restype = py_object
|
_PyUnicode_FromFormat.restype = py_object
|
||||||
|
|
||||||
def PyUnicode_FromFormat(format, *args):
|
def PyUnicode_FromFormat(format, *args):
|
||||||
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
|
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
|
||||||
index dd0c61fd8a..79137e1dc7 100644
|
index dd0c61fd8a..79137e1dc7 100644
|
||||||
--- a/Modules/_ctypes/_ctypes.c
|
--- a/Modules/_ctypes/_ctypes.c
|
||||||
+++ b/Modules/_ctypes/_ctypes.c
|
+++ b/Modules/_ctypes/_ctypes.c
|
||||||
@@ -3174,6 +3174,34 @@ PyCFuncPtr_get_restype(PyCFuncPtrObject *self, void *Py_UNUSED(ignored))
|
@@ -3174,6 +3174,34 @@ PyCFuncPtr_get_restype(PyCFuncPtrObject *self, void *Py_UNUSED(ignored))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+static int
|
+static int
|
||||||
+PyCFuncPtr_set_variadic(PyCFuncPtrObject *self, PyObject *ob)
|
+PyCFuncPtr_set_variadic(PyCFuncPtrObject *self, PyObject *ob)
|
||||||
+{
|
+{
|
||||||
+ StgDictObject *dict = PyObject_stgdict((PyObject *)self);
|
+ StgDictObject *dict = PyObject_stgdict((PyObject *)self);
|
||||||
+ assert(dict);
|
+ assert(dict);
|
||||||
+ int r = PyObject_IsTrue(ob);
|
+ int r = PyObject_IsTrue(ob);
|
||||||
+ if (r == 1) {
|
+ if (r == 1) {
|
||||||
+ dict->flags |= FUNCFLAG_VARIADIC;
|
+ dict->flags |= FUNCFLAG_VARIADIC;
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+ } else if (r == 0) {
|
+ } else if (r == 0) {
|
||||||
+ dict->flags &= ~FUNCFLAG_VARIADIC;
|
+ dict->flags &= ~FUNCFLAG_VARIADIC;
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+ } else {
|
+ } else {
|
||||||
+ return -1;
|
+ return -1;
|
||||||
+ }
|
+ }
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static PyObject *
|
+static PyObject *
|
||||||
+PyCFuncPtr_get_variadic(PyCFuncPtrObject *self)
|
+PyCFuncPtr_get_variadic(PyCFuncPtrObject *self)
|
||||||
+{
|
+{
|
||||||
+ StgDictObject *dict = PyObject_stgdict((PyObject *)self);
|
+ StgDictObject *dict = PyObject_stgdict((PyObject *)self);
|
||||||
+ assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
|
+ assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
|
||||||
+ if (dict->flags & FUNCFLAG_VARIADIC)
|
+ if (dict->flags & FUNCFLAG_VARIADIC)
|
||||||
+ Py_RETURN_TRUE;
|
+ Py_RETURN_TRUE;
|
||||||
+ else
|
+ else
|
||||||
+ Py_RETURN_FALSE;
|
+ Py_RETURN_FALSE;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
static int
|
static int
|
||||||
PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored))
|
PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
@@ -3219,6 +3247,8 @@ static PyGetSetDef PyCFuncPtr_getsets[] = {
|
@@ -3219,6 +3247,8 @@ static PyGetSetDef PyCFuncPtr_getsets[] = {
|
||||||
{ "argtypes", (getter)PyCFuncPtr_get_argtypes,
|
{ "argtypes", (getter)PyCFuncPtr_get_argtypes,
|
||||||
(setter)PyCFuncPtr_set_argtypes,
|
(setter)PyCFuncPtr_set_argtypes,
|
||||||
"specify the argument types", NULL },
|
"specify the argument types", NULL },
|
||||||
+ { "variadic", (getter)PyCFuncPtr_get_variadic, (setter)PyCFuncPtr_set_variadic,
|
+ { "variadic", (getter)PyCFuncPtr_get_variadic, (setter)PyCFuncPtr_set_variadic,
|
||||||
+ "specify if function takes variable number of arguments", NULL },
|
+ "specify if function takes variable number of arguments", NULL },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -5632,6 +5662,7 @@ PyInit__ctypes(void)
|
@@ -5632,6 +5662,7 @@ PyInit__ctypes(void)
|
||||||
PyModule_AddObject(m, "FUNCFLAG_USE_ERRNO", PyLong_FromLong(FUNCFLAG_USE_ERRNO));
|
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_USE_LASTERROR", PyLong_FromLong(FUNCFLAG_USE_LASTERROR));
|
||||||
PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyLong_FromLong(FUNCFLAG_PYTHONAPI));
|
PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyLong_FromLong(FUNCFLAG_PYTHONAPI));
|
||||||
+ PyModule_AddObject(m, "FUNCFLAG_VARIADIC", PyLong_FromLong(FUNCFLAG_VARIADIC));
|
+ PyModule_AddObject(m, "FUNCFLAG_VARIADIC", PyLong_FromLong(FUNCFLAG_VARIADIC));
|
||||||
PyModule_AddStringConstant(m, "__version__", "1.1.0");
|
PyModule_AddStringConstant(m, "__version__", "1.1.0");
|
||||||
|
|
||||||
PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove));
|
PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove));
|
||||||
diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c
|
diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c
|
||||||
index 9cbf9801ad..e7fe11176b 100644
|
index 9cbf9801ad..e7fe11176b 100644
|
||||||
--- a/Modules/_ctypes/callproc.c
|
--- a/Modules/_ctypes/callproc.c
|
||||||
+++ b/Modules/_ctypes/callproc.c
|
+++ b/Modules/_ctypes/callproc.c
|
||||||
@@ -754,7 +756,8 @@ static int _call_function_pointer(int flags,
|
@@ -754,7 +756,8 @@ static int _call_function_pointer(int flags,
|
||||||
ffi_type **atypes,
|
ffi_type **atypes,
|
||||||
ffi_type *restype,
|
ffi_type *restype,
|
||||||
void *resmem,
|
void *resmem,
|
||||||
- int argcount)
|
- int argcount)
|
||||||
+ int argcount,
|
+ int argcount,
|
||||||
+ int argtypecount)
|
+ int argtypecount)
|
||||||
{
|
{
|
||||||
PyThreadState *_save = NULL; /* For Py_BLOCK_THREADS and Py_UNBLOCK_THREADS */
|
PyThreadState *_save = NULL; /* For Py_BLOCK_THREADS and Py_UNBLOCK_THREADS */
|
||||||
PyObject *error_object = NULL;
|
PyObject *error_object = NULL;
|
||||||
@@ -780,15 +783,39 @@ static int _call_function_pointer(int flags,
|
@@ -780,15 +783,39 @@ static int _call_function_pointer(int flags,
|
||||||
if ((flags & FUNCFLAG_CDECL) == 0)
|
if ((flags & FUNCFLAG_CDECL) == 0)
|
||||||
cc = FFI_STDCALL;
|
cc = FFI_STDCALL;
|
||||||
#endif
|
#endif
|
||||||
- if (FFI_OK != ffi_prep_cif(&cif,
|
- if (FFI_OK != ffi_prep_cif(&cif,
|
||||||
- cc,
|
- cc,
|
||||||
- argcount,
|
- argcount,
|
||||||
- restype,
|
- restype,
|
||||||
- atypes)) {
|
- atypes)) {
|
||||||
- PyErr_SetString(PyExc_RuntimeError,
|
- PyErr_SetString(PyExc_RuntimeError,
|
||||||
- "ffi_prep_cif failed");
|
- "ffi_prep_cif failed");
|
||||||
- return -1;
|
- return -1;
|
||||||
+
|
+
|
||||||
+#if HAVE_FFI_PREP_CIF_VAR
|
+#if HAVE_FFI_PREP_CIF_VAR
|
||||||
+ /* Everyone SHOULD set f.variadic=True on variadic function pointers, but
|
+ /* 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
|
+ * 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
|
+ * args are passed than are defined in the prototype, then it must be a
|
||||||
+ * variadic function. */
|
+ * variadic function. */
|
||||||
+ if ((flags & FUNCFLAG_VARIADIC) ||
|
+ if ((flags & FUNCFLAG_VARIADIC) ||
|
||||||
+ (argtypecount != 0 && argcount > argtypecount))
|
+ (argtypecount != 0 && argcount > argtypecount))
|
||||||
+ {
|
+ {
|
||||||
+ if (FFI_OK != ffi_prep_cif_var(&cif,
|
+ if (FFI_OK != ffi_prep_cif_var(&cif,
|
||||||
+ cc,
|
+ cc,
|
||||||
+ argtypecount,
|
+ argtypecount,
|
||||||
+ argcount,
|
+ argcount,
|
||||||
+ restype,
|
+ restype,
|
||||||
+ atypes)) {
|
+ atypes)) {
|
||||||
+ PyErr_SetString(PyExc_RuntimeError,
|
+ PyErr_SetString(PyExc_RuntimeError,
|
||||||
+ "ffi_prep_cif_var failed");
|
+ "ffi_prep_cif_var failed");
|
||||||
+ return -1;
|
+ return -1;
|
||||||
+ }
|
+ }
|
||||||
+ } else {
|
+ } else {
|
||||||
+#endif
|
+#endif
|
||||||
+ if (FFI_OK != ffi_prep_cif(&cif,
|
+ if (FFI_OK != ffi_prep_cif(&cif,
|
||||||
+ cc,
|
+ cc,
|
||||||
+ argcount,
|
+ argcount,
|
||||||
+ restype,
|
+ restype,
|
||||||
+ atypes)) {
|
+ atypes)) {
|
||||||
+ PyErr_SetString(PyExc_RuntimeError,
|
+ PyErr_SetString(PyExc_RuntimeError,
|
||||||
+ "ffi_prep_cif failed");
|
+ "ffi_prep_cif failed");
|
||||||
+ return -1;
|
+ return -1;
|
||||||
+ }
|
+ }
|
||||||
+#if HAVE_FFI_PREP_CIF_VAR
|
+#if HAVE_FFI_PREP_CIF_VAR
|
||||||
}
|
}
|
||||||
+#endif
|
+#endif
|
||||||
|
|
||||||
if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) {
|
if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) {
|
||||||
error_object = _ctypes_get_errobj(&space);
|
error_object = _ctypes_get_errobj(&space);
|
||||||
@@ -1187,9 +1214,8 @@ PyObject *_ctypes_callproc(PPROC pProc,
|
@@ -1187,9 +1214,8 @@ PyObject *_ctypes_callproc(PPROC pProc,
|
||||||
|
|
||||||
if (-1 == _call_function_pointer(flags, pProc, avalues, atypes,
|
if (-1 == _call_function_pointer(flags, pProc, avalues, atypes,
|
||||||
rtype, resbuf,
|
rtype, resbuf,
|
||||||
- Py_SAFE_DOWNCAST(argcount,
|
- Py_SAFE_DOWNCAST(argcount,
|
||||||
- Py_ssize_t,
|
- Py_ssize_t,
|
||||||
- int)))
|
- int)))
|
||||||
+ 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)))
|
+ Py_SAFE_DOWNCAST(argtype_count, Py_ssize_t, int)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h
|
diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h
|
||||||
index e58f85233c..e45975f6ad 100644
|
index e58f85233c..e45975f6ad 100644
|
||||||
--- a/Modules/_ctypes/ctypes.h
|
--- a/Modules/_ctypes/ctypes.h
|
||||||
+++ b/Modules/_ctypes/ctypes.h
|
+++ b/Modules/_ctypes/ctypes.h
|
||||||
@@ -285,6 +285,7 @@ PyObject *_ctypes_callproc(PPROC pProc,
|
@@ -285,6 +285,7 @@ PyObject *_ctypes_callproc(PPROC pProc,
|
||||||
#define FUNCFLAG_PYTHONAPI 0x4
|
#define FUNCFLAG_PYTHONAPI 0x4
|
||||||
#define FUNCFLAG_USE_ERRNO 0x8
|
#define FUNCFLAG_USE_ERRNO 0x8
|
||||||
#define FUNCFLAG_USE_LASTERROR 0x10
|
#define FUNCFLAG_USE_LASTERROR 0x10
|
||||||
+#define FUNCFLAG_VARIADIC 0x20
|
+#define FUNCFLAG_VARIADIC 0x20
|
||||||
|
|
||||||
#define TYPEFLAG_ISPOINTER 0x100
|
#define TYPEFLAG_ISPOINTER 0x100
|
||||||
#define TYPEFLAG_HASPOINTER 0x200
|
#define TYPEFLAG_HASPOINTER 0x200
|
||||||
diff --git a/setup.py b/setup.py
|
diff --git a/setup.py b/setup.py
|
||||||
index bf90600eaa..48ff120e9a 100644
|
index bf90600eaa..48ff120e9a 100644
|
||||||
--- a/setup.py
|
--- a/setup.py
|
||||||
+++ b/setup.py
|
+++ b/setup.py
|
||||||
@@ -142,6 +142,13 @@ def macosx_sdk_root():
|
@@ -142,6 +142,13 @@ def macosx_sdk_root():
|
||||||
|
|
||||||
return MACOS_SDK_ROOT
|
return MACOS_SDK_ROOT
|
||||||
|
|
||||||
+def is_macosx_at_least(vers):
|
+def is_macosx_at_least(vers):
|
||||||
+ if host_platform == 'darwin':
|
+ if host_platform == 'darwin':
|
||||||
+ dep_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
|
+ dep_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
|
||||||
+ if dep_target:
|
+ if dep_target:
|
||||||
+ return tuple(map(int, str(dep_target).split('.'))) >= vers
|
+ return tuple(map(int, str(dep_target).split('.'))) >= vers
|
||||||
+ return False
|
+ return False
|
||||||
+
|
+
|
||||||
def is_macosx_sdk_path(path):
|
def is_macosx_sdk_path(path):
|
||||||
"""
|
"""
|
||||||
Returns True if 'path' can be located in an OSX SDK
|
Returns True if 'path' can be located in an OSX SDK
|
||||||
@@ -150,6 +157,13 @@ def is_macosx_sdk_path(path):
|
@@ -150,6 +157,13 @@ def is_macosx_sdk_path(path):
|
||||||
or path.startswith('/System/')
|
or path.startswith('/System/')
|
||||||
or path.startswith('/Library/') )
|
or path.startswith('/Library/') )
|
||||||
|
|
||||||
+def grep_headers_for(function, headers):
|
+def grep_headers_for(function, headers):
|
||||||
+ for header in headers:
|
+ for header in headers:
|
||||||
+ with open(header, 'r') as f:
|
+ with open(header, 'r') as f:
|
||||||
+ if function in f.read():
|
+ if function in f.read():
|
||||||
+ return True
|
+ return True
|
||||||
+ return False
|
+ return False
|
||||||
+
|
+
|
||||||
def find_file(filename, std_dirs, paths):
|
def find_file(filename, std_dirs, paths):
|
||||||
"""Searches for the directory where a given file is located,
|
"""Searches for the directory where a given file is located,
|
||||||
and returns a possibly-empty list of additional directories, or None
|
and returns a possibly-empty list of additional directories, or None
|
||||||
@@ -1972,7 +1986,11 @@ class PyBuildExt(build_ext):
|
@@ -1972,7 +1986,11 @@ class PyBuildExt(build_ext):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def detect_ctypes(self, inc_dirs, lib_dirs):
|
def detect_ctypes(self, inc_dirs, lib_dirs):
|
||||||
- self.use_system_libffi = False
|
- self.use_system_libffi = False
|
||||||
+ if not sysconfig.get_config_var("LIBFFI_INCLUDEDIR") and is_macosx_at_least((10,15)):
|
+ if not sysconfig.get_config_var("LIBFFI_INCLUDEDIR") and is_macosx_at_least((10,15)):
|
||||||
+ self.use_system_libffi = True
|
+ self.use_system_libffi = True
|
||||||
+ else:
|
+ else:
|
||||||
+ self.use_system_libffi = '--with-system-ffi' in sysconfig.get_config_var("CONFIG_ARGS")
|
+ self.use_system_libffi = '--with-system-ffi' in sysconfig.get_config_var("CONFIG_ARGS")
|
||||||
+
|
+
|
||||||
include_dirs = []
|
include_dirs = []
|
||||||
extra_compile_args = []
|
extra_compile_args = []
|
||||||
extra_link_args = []
|
extra_link_args = []
|
||||||
@@ -2018,30 +2036,47 @@ class PyBuildExt(build_ext):
|
@@ -2018,30 +2036,47 @@ class PyBuildExt(build_ext):
|
||||||
libraries=['m'])
|
libraries=['m'])
|
||||||
self.extensions.extend([ext, ext_test])
|
self.extensions.extend([ext, ext_test])
|
||||||
|
|
||||||
+ ffi_inc = sysconfig.get_config_var("LIBFFI_INCLUDEDIR")
|
+ ffi_inc = sysconfig.get_config_var("LIBFFI_INCLUDEDIR")
|
||||||
+ ffi_lib = None
|
+ ffi_lib = None
|
||||||
+
|
+
|
||||||
if host_platform == 'darwin':
|
if host_platform == 'darwin':
|
||||||
- if '--with-system-ffi' not in sysconfig.get_config_var("CONFIG_ARGS"):
|
- if '--with-system-ffi' not in sysconfig.get_config_var("CONFIG_ARGS"):
|
||||||
+ if not self.use_system_libffi:
|
+ if not self.use_system_libffi:
|
||||||
return
|
return
|
||||||
- # OS X 10.5 comes with libffi.dylib; the include files are
|
- # OS X 10.5 comes with libffi.dylib; the include files are
|
||||||
- # in /usr/include/ffi
|
- # in /usr/include/ffi
|
||||||
- inc_dirs.append('/usr/include/ffi')
|
- inc_dirs.append('/usr/include/ffi')
|
||||||
-
|
-
|
||||||
- ffi_inc = [sysconfig.get_config_var("LIBFFI_INCLUDEDIR")]
|
- ffi_inc = [sysconfig.get_config_var("LIBFFI_INCLUDEDIR")]
|
||||||
- if not ffi_inc or ffi_inc[0] == '':
|
- if not ffi_inc or ffi_inc[0] == '':
|
||||||
- ffi_inc = find_file('ffi.h', [], inc_dirs)
|
- ffi_inc = find_file('ffi.h', [], inc_dirs)
|
||||||
- if ffi_inc is not None:
|
- if ffi_inc is not None:
|
||||||
- ffi_h = ffi_inc[0] + '/ffi.h'
|
- ffi_h = ffi_inc[0] + '/ffi.h'
|
||||||
+ ffi_in_sdk = os.path.join(macosx_sdk_root(), "usr/include/ffi")
|
+ ffi_in_sdk = os.path.join(macosx_sdk_root(), "usr/include/ffi")
|
||||||
+ if os.path.exists(ffi_in_sdk):
|
+ if os.path.exists(ffi_in_sdk):
|
||||||
+ ffi_inc = ffi_in_sdk
|
+ ffi_inc = ffi_in_sdk
|
||||||
+ ffi_lib = 'ffi'
|
+ ffi_lib = 'ffi'
|
||||||
+ else:
|
+ else:
|
||||||
+ # OS X 10.5 comes with libffi.dylib; the include files are
|
+ # OS X 10.5 comes with libffi.dylib; the include files are
|
||||||
+ # in /usr/include/ffi
|
+ # in /usr/include/ffi
|
||||||
+ inc_dirs.append('/usr/include/ffi')
|
+ inc_dirs.append('/usr/include/ffi')
|
||||||
+
|
+
|
||||||
+ if not ffi_inc:
|
+ if not ffi_inc:
|
||||||
+ found = find_file('ffi.h', [], inc_dirs)
|
+ found = find_file('ffi.h', [], inc_dirs)
|
||||||
+ if found:
|
+ if found:
|
||||||
+ ffi_inc = found[0]
|
+ ffi_inc = found[0]
|
||||||
+ if ffi_inc:
|
+ if ffi_inc:
|
||||||
+ ffi_h = ffi_inc + '/ffi.h'
|
+ ffi_h = ffi_inc + '/ffi.h'
|
||||||
if not os.path.exists(ffi_h):
|
if not os.path.exists(ffi_h):
|
||||||
ffi_inc = None
|
ffi_inc = None
|
||||||
print('Header file {} does not exist'.format(ffi_h))
|
print('Header file {} does not exist'.format(ffi_h))
|
||||||
- ffi_lib = None
|
- ffi_lib = None
|
||||||
- if ffi_inc is not None:
|
- if ffi_inc is not None:
|
||||||
- for lib_name in ('ffi', 'ffi_pic'):
|
- for lib_name in ('ffi', 'ffi_pic'):
|
||||||
+
|
+
|
||||||
+ if ffi_lib is None and ffi_inc:
|
+ if ffi_lib is None and ffi_inc:
|
||||||
+ for lib_name in ('ffi_convenience', 'ffi_pic', 'ffi'):
|
+ for lib_name in ('ffi_convenience', 'ffi_pic', 'ffi'):
|
||||||
if (self.compiler.find_library_file(lib_dirs, lib_name)):
|
if (self.compiler.find_library_file(lib_dirs, lib_name)):
|
||||||
ffi_lib = lib_name
|
ffi_lib = lib_name
|
||||||
break
|
break
|
||||||
|
|
||||||
if ffi_inc and ffi_lib:
|
if ffi_inc and ffi_lib:
|
||||||
- ext.include_dirs.extend(ffi_inc)
|
- ext.include_dirs.extend(ffi_inc)
|
||||||
+ ffi_headers = glob(os.path.join(ffi_inc, '*.h'))
|
+ ffi_headers = glob(os.path.join(ffi_inc, '*.h'))
|
||||||
+ if grep_headers_for('ffi_closure_alloc', ffi_headers):
|
+ if grep_headers_for('ffi_closure_alloc', ffi_headers):
|
||||||
+ try:
|
+ try:
|
||||||
+ sources.remove('_ctypes/malloc_closure.c')
|
+ sources.remove('_ctypes/malloc_closure.c')
|
||||||
+ except ValueError:
|
+ except ValueError:
|
||||||
+ pass
|
+ pass
|
||||||
+ if grep_headers_for('ffi_prep_cif_var', ffi_headers):
|
+ if grep_headers_for('ffi_prep_cif_var', ffi_headers):
|
||||||
+ ext.extra_compile_args.append("-DHAVE_FFI_PREP_CIF_VAR=1")
|
+ ext.extra_compile_args.append("-DHAVE_FFI_PREP_CIF_VAR=1")
|
||||||
+ ext.include_dirs.append(ffi_inc)
|
+ ext.include_dirs.append(ffi_inc)
|
||||||
ext.libraries.append(ffi_lib)
|
ext.libraries.append(ffi_lib)
|
||||||
self.use_system_libffi = True
|
self.use_system_libffi = True
|
||||||
|
|
||||||
--
|
--
|
||||||
2.30.1 (Apple Git-130)
|
2.30.1 (Apple Git-130)
|
||||||
|
|
||||||
|
|||||||
@@ -1,36 +1,36 @@
|
|||||||
From 604d95e235d86465b8c17f02095edcaf18464d4c Mon Sep 17 00:00:00 2001
|
From 604d95e235d86465b8c17f02095edcaf18464d4c Mon Sep 17 00:00:00 2001
|
||||||
From: Lawrence D'Anna <64555057+lawrence-danna-apple@users.noreply.github.com>
|
From: Lawrence D'Anna <64555057+lawrence-danna-apple@users.noreply.github.com>
|
||||||
Date: Tue, 30 Jun 2020 02:15:46 -0700
|
Date: Tue, 30 Jun 2020 02:15:46 -0700
|
||||||
Subject: [PATCH] bpo-41100: fix _decimal for arm64 Mac OS (GH-21228)
|
Subject: [PATCH] bpo-41100: fix _decimal for arm64 Mac OS (GH-21228)
|
||||||
|
|
||||||
Patch by Lawrence Danna.
|
Patch by Lawrence Danna.
|
||||||
---
|
---
|
||||||
.../Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst | 1 +
|
.../Core and Builtins/2020-06-30-04-44-29.bpo-41100.PJwA6F.rst | 1 +
|
||||||
Modules/_decimal/libmpdec/mpdecimal.h | 3 +++
|
Modules/_decimal/libmpdec/mpdecimal.h | 3 +++
|
||||||
2 files changed, 4 insertions(+)
|
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
|
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
|
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
|
new file mode 100644
|
||||||
index 0000000000..d6176d69f0
|
index 0000000000..d6176d69f0
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/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
|
||||||
@@ -0,0 +1 @@
|
@@ -0,0 +1 @@
|
||||||
+add arm64 to the allowable Mac OS arches in mpdecimal.h
|
+add arm64 to the allowable Mac OS arches in mpdecimal.h
|
||||||
\ No newline at end of file
|
\ No newline at end of file
|
||||||
diff --git a/Modules/_decimal/libmpdec/mpdecimal.h b/Modules/_decimal/libmpdec/mpdecimal.h
|
diff --git a/Modules/_decimal/libmpdec/mpdecimal.h b/Modules/_decimal/libmpdec/mpdecimal.h
|
||||||
index 108b76efa8..35ce429f60 100644
|
index 108b76efa8..35ce429f60 100644
|
||||||
--- a/Modules/_decimal/libmpdec/mpdecimal.h
|
--- a/Modules/_decimal/libmpdec/mpdecimal.h
|
||||||
+++ b/Modules/_decimal/libmpdec/mpdecimal.h
|
+++ b/Modules/_decimal/libmpdec/mpdecimal.h
|
||||||
@@ -135,6 +135,9 @@ const char *mpd_version(void);
|
@@ -135,6 +135,9 @@ const char *mpd_version(void);
|
||||||
#elif defined(__x86_64__)
|
#elif defined(__x86_64__)
|
||||||
#define CONFIG_64
|
#define CONFIG_64
|
||||||
#define ASM
|
#define ASM
|
||||||
+ #elif defined(__arm64__)
|
+ #elif defined(__arm64__)
|
||||||
+ #define CONFIG_64
|
+ #define CONFIG_64
|
||||||
+ #define ANSI
|
+ #define ANSI
|
||||||
#else
|
#else
|
||||||
#error "unknown architecture for universal build."
|
#error "unknown architecture for universal build."
|
||||||
#endif
|
#endif
|
||||||
--
|
--
|
||||||
2.30.1 (Apple Git-130)
|
2.30.1 (Apple Git-130)
|
||||||
|
|||||||
@@ -1,30 +1,30 @@
|
|||||||
From 245427d207ee88a4ba26a66c3de350bcbcc036f2 Mon Sep 17 00:00:00 2001
|
From 245427d207ee88a4ba26a66c3de350bcbcc036f2 Mon Sep 17 00:00:00 2001
|
||||||
From: Ronald Oussoren <ronaldoussoren@mac.com>
|
From: Ronald Oussoren <ronaldoussoren@mac.com>
|
||||||
Date: Sat, 14 Nov 2020 16:07:47 +0100
|
Date: Sat, 14 Nov 2020 16:07:47 +0100
|
||||||
Subject: [PATCH] bpo-42351: Avoid error when opening header with non-UTF8
|
Subject: [PATCH] bpo-42351: Avoid error when opening header with non-UTF8
|
||||||
encoding (GH-23279)
|
encoding (GH-23279)
|
||||||
|
|
||||||
grep_headers_for() would error out when a header contained
|
grep_headers_for() would error out when a header contained
|
||||||
text that cannot be interpreted as UTF-8.
|
text that cannot be interpreted as UTF-8.
|
||||||
|
|
||||||
cherry-picked from 7a27c7ed4b by Pedro Fonini <fonini@ip.tv>
|
cherry-picked from 7a27c7ed4b by Pedro Fonini <fonini@ip.tv>
|
||||||
---
|
---
|
||||||
setup.py | 2 +-
|
setup.py | 2 +-
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
diff --git a/setup.py b/setup.py
|
diff --git a/setup.py b/setup.py
|
||||||
index f211989aac..467362813d 100644
|
index f211989aac..467362813d 100644
|
||||||
--- a/setup.py
|
--- a/setup.py
|
||||||
+++ b/setup.py
|
+++ b/setup.py
|
||||||
@@ -159,7 +159,7 @@ def is_macosx_sdk_path(path):
|
@@ -159,7 +159,7 @@ def is_macosx_sdk_path(path):
|
||||||
|
|
||||||
def grep_headers_for(function, headers):
|
def grep_headers_for(function, headers):
|
||||||
for header in headers:
|
for header in headers:
|
||||||
- with open(header, 'r') as f:
|
- with open(header, 'r') as f:
|
||||||
+ with open(header, 'r', errors='surrogateescape') as f:
|
+ with open(header, 'r', errors='surrogateescape') as f:
|
||||||
if function in f.read():
|
if function in f.read():
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
--
|
--
|
||||||
2.34.1
|
2.34.1
|
||||||
|
|
||||||
|
|||||||
@@ -115,6 +115,6 @@ DEF
|
|||||||
|
|
||||||
#assert_success
|
#assert_success
|
||||||
assert_output <<OUT
|
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
|
OUT
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,3 +55,38 @@ OUT
|
|||||||
|
|
||||||
refute [ -d "${PYENV_ROOT}/versions/3.6.2" ]
|
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" ]
|
||||||
|
}
|
||||||
|
|||||||
@@ -195,12 +195,28 @@ OUT
|
|||||||
unstub pyenv-help
|
unstub pyenv-help
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "too many arguments for pyenv-uninstall" {
|
@test "more than one argument for pyenv-uninstall" {
|
||||||
stub pyenv-help 'uninstall : true'
|
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
|
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" {
|
@test "show help for pyenv-uninstall" {
|
||||||
|
|||||||
@@ -82,3 +82,37 @@ IN
|
|||||||
run pyenv-version-file-read my-version
|
run pyenv-version-file-read my-version
|
||||||
assert_success "3.9.3:3.8.9:2.7.16"
|
assert_success "3.9.3:3.8.9:2.7.16"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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
|
||||||
|
IN
|
||||||
|
run pyenv-version-file-read my-version
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,6 +17,14 @@ stub_system_python() {
|
|||||||
touch "$stub" && chmod +x "$stub"
|
touch "$stub" && chmod +x "$stub"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
create_executable() {
|
||||||
|
local name="$1"
|
||||||
|
local bin="${PYENV_TEST_DIR}/bin"
|
||||||
|
mkdir -p "$bin"
|
||||||
|
sed -Ee '1s/^ +//' > "${bin}/$name"
|
||||||
|
chmod +x "${bin}/$name"
|
||||||
|
}
|
||||||
|
|
||||||
@test "no versions installed" {
|
@test "no versions installed" {
|
||||||
stub_system_python
|
stub_system_python
|
||||||
assert [ ! -d "${PYENV_ROOT}/versions" ]
|
assert [ ! -d "${PYENV_ROOT}/versions" ]
|
||||||
@@ -161,3 +169,44 @@ OUT
|
|||||||
run pyenv-versions --bare
|
run pyenv-versions --bare
|
||||||
assert_success ".venv"
|
assert_success ".venv"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "sort supports version sorting" {
|
||||||
|
create_version "1.9.0"
|
||||||
|
create_version "1.53.0"
|
||||||
|
create_version "1.218.0"
|
||||||
|
create_executable sort <<SH
|
||||||
|
#!$BASH
|
||||||
|
if [ "\$1" == "--version-sort" ]; then
|
||||||
|
echo "${PYENV_ROOT}/versions/1.9.0"
|
||||||
|
echo "${PYENV_ROOT}/versions/1.53.0"
|
||||||
|
echo "${PYENV_ROOT}/versions/1.218.0"
|
||||||
|
else exit 1
|
||||||
|
fi
|
||||||
|
SH
|
||||||
|
|
||||||
|
run pyenv-versions --bare
|
||||||
|
assert_success
|
||||||
|
assert_output <<OUT
|
||||||
|
1.9.0
|
||||||
|
1.53.0
|
||||||
|
1.218.0
|
||||||
|
OUT
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "sort doesn't support version sorting" {
|
||||||
|
create_version "1.9.0"
|
||||||
|
create_version "1.53.0"
|
||||||
|
create_version "1.218.0"
|
||||||
|
create_executable sort <<SH
|
||||||
|
#!$BASH
|
||||||
|
exit 1
|
||||||
|
SH
|
||||||
|
|
||||||
|
run pyenv-versions --bare
|
||||||
|
assert_success
|
||||||
|
assert_output <<OUT
|
||||||
|
1.218.0
|
||||||
|
1.53.0
|
||||||
|
1.9.0
|
||||||
|
OUT
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user