diff --git a/.github/workflows/test_actions.yml b/.github/workflows/test_actions.yml index 4127ebb..a8d4d3e 100644 --- a/.github/workflows/test_actions.yml +++ b/.github/workflows/test_actions.yml @@ -11,7 +11,7 @@ jobs: strategy: matrix: os: [windows-latest, ubuntu-latest] - python-version: [3.9, '3.10', 3.11, 3.12, 3.13] + python-version: [3.9, '3.10', 3.11, 3.12, 3.13, 3.13t, pypy3.10, pypy3.11] steps: - name: Check out repo uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -21,12 +21,22 @@ jobs: python-version: ${{ matrix.python-version }} - name: Check Python version run: | - import sys + import sys, sysconfig version = sys.version_info[:2] - expected_version = tuple(map(int, "${{ matrix.python-version }}".split("."))) + expected_version = tuple(map(int, "${{ matrix.python-version }}".removeprefix("pypy").removesuffix("t").split("."))) if version != expected_version: print(f"::error title=Test Failure::The Python version does not match. Got {version}, expected {expected_version}.") sys.exit(1) + implementation = sys.implementation.name + expected_implementation = "pypy" if "${{ matrix.python-version }}".startswith("pypy") else "cpython" + if implementation != expected_implementation: + print(f"::error title=Test Failure::The Python implementation does not match. Got {implementation}, expected {expected_implementation}.") + sys.exit(1) + threading = "free-threading" if sysconfig.get_config_var("Py_GIL_DISABLED") else "GIL" + expected_threading = "free-threading" if "${{ matrix.python-version }}".endswith("t") else "GIL" + if threading != expected_threading: + print(f"::error title=Test Failure::The Python threading does not match. Got {threading}, expected {expected_threading}.") + sys.exit(1) shell: python test_setup_poetry: @@ -35,7 +45,7 @@ jobs: strategy: matrix: os: [windows-latest, ubuntu-latest] - python-version: [3.9, '3.10', 3.11, 3.12, 3.13] + python-version: [3.9, '3.10', 3.11, 3.12, 3.13, pypy3.10, pypy3.11] steps: - name: Check out repo uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -62,7 +72,7 @@ jobs: strategy: matrix: os: [windows-latest, ubuntu-latest] - python-version: [3.9, '3.10', 3.11, 3.12, 3.13] + python-version: [3.9, '3.10', 3.11, 3.12, 3.13, pypy3.10, pypy3.11] steps: - name: Check out repo uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -94,7 +104,7 @@ jobs: strategy: matrix: os: [windows-latest, ubuntu-latest] - python-version: [3.9, '3.10', 3.11, 3.12, 3.13] + python-version: [3.9, '3.10', 3.11, 3.12, 3.13, pypy3.10, pypy3.11] steps: - name: Check out repo uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 diff --git a/README.md b/README.md index a4af285..3fa3501 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ - [Outputs](#outputs) - [`python-version`](#python-version-1) - [`python-path`](#python-path) + - [Environment Variables](#environment-variables) + - [`pythonVersion`](#pythonversion) - [`ni/python-actions/setup-poetry`](#nipython-actionssetup-poetry) - [Usage](#usage-1) - [Inputs](#inputs-1) @@ -82,6 +84,12 @@ steps: key: venv-${{ runner.os }}-py${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('poetry.lock') }} ``` +`python-version` is unique across implementations (CPython vs. PyPy) and free-threaded builds: + +- CPython: "3.13.4". +- CPython with free-threading: "3.13.4t" +- PyPy: "pypy3.11.11-v7.3.19" + #### `python-path` `actions/setup-python` sets the `pythonLocation` environment variable to the **directory** @@ -96,6 +104,13 @@ steps: - run: pipx install --python ${{ steps.setup-python.outputs.python-version }} ``` +### Environment Variables + +#### `pythonVersion` + +This is the same as `outputs.python-version` and is mainly intended for use in +`ni/python-actions/setup-poetry`. + ## `ni/python-actions/setup-poetry` The `setup-poetry` action installs Poetry, adds it to the PATH, and caches it to speed up diff --git a/setup-poetry/action.yml b/setup-poetry/action.yml index 379fb67..5664398 100644 --- a/setup-poetry/action.yml +++ b/setup-poetry/action.yml @@ -17,14 +17,12 @@ outputs: runs: using: composite steps: - - name: Get Python version - id: get-python-version + - name: Check that setup-python was called run: | - if [ ! -d "$pythonLocation" ]; then + if [ ! -d "$pythonLocation" -o -z "$pythonVersion" ]; then echo "You must use the setup-python action before using this action." exit 1 fi - "$pythonLocation/python" -c "import platform; print(f'python-version={platform.python_version()}')" >> "$GITHUB_OUTPUT" shell: bash - name: Set paths (Linux/Mac) if: runner.os != 'Windows' @@ -57,11 +55,11 @@ runs: path: | ${{ steps.copy-paths.outputs.poetry-bin-dir }}/poetry* ${{ steps.copy-paths.outputs.poetry-home }} - key: poetry${{ inputs.poetry-version }}-${{ runner.os }}-py${{ steps.get-python-version.outputs.python-version }} + key: poetry${{ inputs.poetry-version }}-${{ runner.os }}-py${{ env.pythonVersion }} - name: Install Poetry if: steps.cache-poetry.outputs.cache-hit != 'true' run: | - "$pythonLocation/python" -m venv "$POETRY_HOME" + python -m venv "$POETRY_HOME" "$POETRY_HOME_BIN/python" -m pip install poetry==${{ inputs.poetry-version }} mkdir -p "$POETRY_BIN_DIR" ln -s "$POETRY_HOME_BIN/poetry"* "$POETRY_BIN_DIR/" diff --git a/setup-python/action.yml b/setup-python/action.yml index bda922d..3cee10b 100644 --- a/setup-python/action.yml +++ b/setup-python/action.yml @@ -7,7 +7,7 @@ outputs: python-path: value: ${{ steps.setup-python.outputs.python-path }} python-version: - value: ${{ steps.setup-python.outputs.python-version }} + value: ${{ steps.get-python-version.outputs.python-version }} runs: using: composite steps: @@ -16,3 +16,22 @@ runs: id: setup-python with: python-version: ${{ inputs.python-version }} + # Workaround for https://github.com/actions/setup-python/issues/1109 - + # Python-version output for PyPy isn't unique across different versions + - name: Get Python version + id: get-python-version + run: | + import os, platform, sys, sysconfig + if sys.implementation.name == "pypy": + version = f"pypy{platform.python_version()}-v{'.'.join(map(str,sys.implementation.version[:3]))}" + else: + version = platform.python_version() + # Also take free-threading into account + if sysconfig.get_config_var("Py_GIL_DISABLED"): + version += "t" + with open(os.environ["GITHUB_OUTPUT"], "a") as output: + print(f"python-version={version}", file=output) + shell: python + - name: Add pythonVersion environment variable + run: echo "pythonVersion=${{ steps.get-python-version.outputs.python-version }}" >> "$GITHUB_ENV" + shell: bash \ No newline at end of file