Skip to content

Commit 49cd7a9

Browse files
authored
setup-python, setup-poetry: Enable PyPy support (#11)
* github: Test setup-python and setup-poetry with pypy * github: Handle pypy in setup-python test * setup-python: Get Python version and set env.pythonVersion * setup-poetry: Use env.pythonVersion * tests: Add free-threading builds * tests: Free-threaded builds are only for Python 3.13+ * tests: Test setup-poetry with free-threading too * setup-poetry: Add `ls -al` for debugging * tests: Add a temporary test of $pythonLocation * tests: More hacks * setup-poetry: Don't use $pythonLocation due to actions/setup-python#1138 * tests: Remove test_python_location * tests: Disable 3.13t for setup-poetry test * setup-python: Document new python-version behavior and env.pythonVersion
1 parent a3bfe1b commit 49cd7a9

File tree

4 files changed

+55
-13
lines changed

4 files changed

+55
-13
lines changed

.github/workflows/test_actions.yml

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
strategy:
1212
matrix:
1313
os: [windows-latest, ubuntu-latest]
14-
python-version: [3.9, '3.10', 3.11, 3.12, 3.13]
14+
python-version: [3.9, '3.10', 3.11, 3.12, 3.13, 3.13t, pypy3.10, pypy3.11]
1515
steps:
1616
- name: Check out repo
1717
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -21,12 +21,22 @@ jobs:
2121
python-version: ${{ matrix.python-version }}
2222
- name: Check Python version
2323
run: |
24-
import sys
24+
import sys, sysconfig
2525
version = sys.version_info[:2]
26-
expected_version = tuple(map(int, "${{ matrix.python-version }}".split(".")))
26+
expected_version = tuple(map(int, "${{ matrix.python-version }}".removeprefix("pypy").removesuffix("t").split(".")))
2727
if version != expected_version:
2828
print(f"::error title=Test Failure::The Python version does not match. Got {version}, expected {expected_version}.")
2929
sys.exit(1)
30+
implementation = sys.implementation.name
31+
expected_implementation = "pypy" if "${{ matrix.python-version }}".startswith("pypy") else "cpython"
32+
if implementation != expected_implementation:
33+
print(f"::error title=Test Failure::The Python implementation does not match. Got {implementation}, expected {expected_implementation}.")
34+
sys.exit(1)
35+
threading = "free-threading" if sysconfig.get_config_var("Py_GIL_DISABLED") else "GIL"
36+
expected_threading = "free-threading" if "${{ matrix.python-version }}".endswith("t") else "GIL"
37+
if threading != expected_threading:
38+
print(f"::error title=Test Failure::The Python threading does not match. Got {threading}, expected {expected_threading}.")
39+
sys.exit(1)
3040
shell: python
3141

3242
test_setup_poetry:
@@ -35,7 +45,7 @@ jobs:
3545
strategy:
3646
matrix:
3747
os: [windows-latest, ubuntu-latest]
38-
python-version: [3.9, '3.10', 3.11, 3.12, 3.13]
48+
python-version: [3.9, '3.10', 3.11, 3.12, 3.13, pypy3.10, pypy3.11]
3949
steps:
4050
- name: Check out repo
4151
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -62,7 +72,7 @@ jobs:
6272
strategy:
6373
matrix:
6474
os: [windows-latest, ubuntu-latest]
65-
python-version: [3.9, '3.10', 3.11, 3.12, 3.13]
75+
python-version: [3.9, '3.10', 3.11, 3.12, 3.13, pypy3.10, pypy3.11]
6676
steps:
6777
- name: Check out repo
6878
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -94,7 +104,7 @@ jobs:
94104
strategy:
95105
matrix:
96106
os: [windows-latest, ubuntu-latest]
97-
python-version: [3.9, '3.10', 3.11, 3.12, 3.13]
107+
python-version: [3.9, '3.10', 3.11, 3.12, 3.13, pypy3.10, pypy3.11]
98108
steps:
99109
- name: Check out repo
100110
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
- [Outputs](#outputs)
1414
- [`python-version`](#python-version-1)
1515
- [`python-path`](#python-path)
16+
- [Environment Variables](#environment-variables)
17+
- [`pythonVersion`](#pythonversion)
1618
- [`ni/python-actions/setup-poetry`](#nipython-actionssetup-poetry)
1719
- [Usage](#usage-1)
1820
- [Inputs](#inputs-1)
@@ -82,6 +84,12 @@ steps:
8284
key: venv-${{ runner.os }}-py${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('poetry.lock') }}
8385
```
8486

87+
`python-version` is unique across implementations (CPython vs. PyPy) and free-threaded builds:
88+
89+
- CPython: "3.13.4".
90+
- CPython with free-threading: "3.13.4t"
91+
- PyPy: "pypy3.11.11-v7.3.19"
92+
8593
#### `python-path`
8694

8795
`actions/setup-python` sets the `pythonLocation` environment variable to the **directory**
@@ -96,6 +104,13 @@ steps:
96104
- run: pipx install <package> --python ${{ steps.setup-python.outputs.python-version }}
97105
```
98106

107+
### Environment Variables
108+
109+
#### `pythonVersion`
110+
111+
This is the same as `outputs.python-version` and is mainly intended for use in
112+
`ni/python-actions/setup-poetry`.
113+
99114
## `ni/python-actions/setup-poetry`
100115

101116
The `setup-poetry` action installs Poetry, adds it to the PATH, and caches it to speed up

setup-poetry/action.yml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,12 @@ outputs:
1717
runs:
1818
using: composite
1919
steps:
20-
- name: Get Python version
21-
id: get-python-version
20+
- name: Check that setup-python was called
2221
run: |
23-
if [ ! -d "$pythonLocation" ]; then
22+
if [ ! -d "$pythonLocation" -o -z "$pythonVersion" ]; then
2423
echo "You must use the setup-python action before using this action."
2524
exit 1
2625
fi
27-
"$pythonLocation/python" -c "import platform; print(f'python-version={platform.python_version()}')" >> "$GITHUB_OUTPUT"
2826
shell: bash
2927
- name: Set paths (Linux/Mac)
3028
if: runner.os != 'Windows'
@@ -57,11 +55,11 @@ runs:
5755
path: |
5856
${{ steps.copy-paths.outputs.poetry-bin-dir }}/poetry*
5957
${{ steps.copy-paths.outputs.poetry-home }}
60-
key: poetry${{ inputs.poetry-version }}-${{ runner.os }}-py${{ steps.get-python-version.outputs.python-version }}
58+
key: poetry${{ inputs.poetry-version }}-${{ runner.os }}-py${{ env.pythonVersion }}
6159
- name: Install Poetry
6260
if: steps.cache-poetry.outputs.cache-hit != 'true'
6361
run: |
64-
"$pythonLocation/python" -m venv "$POETRY_HOME"
62+
python -m venv "$POETRY_HOME"
6563
"$POETRY_HOME_BIN/python" -m pip install poetry==${{ inputs.poetry-version }}
6664
mkdir -p "$POETRY_BIN_DIR"
6765
ln -s "$POETRY_HOME_BIN/poetry"* "$POETRY_BIN_DIR/"

setup-python/action.yml

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ outputs:
77
python-path:
88
value: ${{ steps.setup-python.outputs.python-path }}
99
python-version:
10-
value: ${{ steps.setup-python.outputs.python-version }}
10+
value: ${{ steps.get-python-version.outputs.python-version }}
1111
runs:
1212
using: composite
1313
steps:
@@ -16,3 +16,22 @@ runs:
1616
id: setup-python
1717
with:
1818
python-version: ${{ inputs.python-version }}
19+
# Workaround for https://github.com/actions/setup-python/issues/1109 -
20+
# Python-version output for PyPy isn't unique across different versions
21+
- name: Get Python version
22+
id: get-python-version
23+
run: |
24+
import os, platform, sys, sysconfig
25+
if sys.implementation.name == "pypy":
26+
version = f"pypy{platform.python_version()}-v{'.'.join(map(str,sys.implementation.version[:3]))}"
27+
else:
28+
version = platform.python_version()
29+
# Also take free-threading into account
30+
if sysconfig.get_config_var("Py_GIL_DISABLED"):
31+
version += "t"
32+
with open(os.environ["GITHUB_OUTPUT"], "a") as output:
33+
print(f"python-version={version}", file=output)
34+
shell: python
35+
- name: Add pythonVersion environment variable
36+
run: echo "pythonVersion=${{ steps.get-python-version.outputs.python-version }}" >> "$GITHUB_ENV"
37+
shell: bash

0 commit comments

Comments
 (0)