Skip to content

Commit

Permalink
ci: support development releases of Python (#3419)
Browse files Browse the repository at this point in the history
* ci: support development releases of Python

* fix: better PyPy support

* fix: patch over a few more pypy issues

* Try to patch

* Properly follow pep667

* Fix typo

* Whoops, 667 not in yet

* For testing

* More testing

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Try to backport

* Try to simplify fix

* Nail down the fix

* Try pypy workaround

* Typo

* one last typo

* Replacing 0x03110000 with 0x030B0000

* Add TODO. Drop PyPy

* Fix typo

* Revert catch upgrade

* fix: minor cleanup, try pypy again

Co-authored-by: Aaron Gokaslan <skylion.aaron@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Ralf W. Grosse-Kunstleve <rwgk@google.com>
  • Loading branch information
4 people authored Nov 17, 2021
1 parent 1eb5996 commit 72282f7
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 17 deletions.
11 changes: 4 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,14 @@ jobs:
- '3.6'
- '3.9'
- '3.10'
# - '3.11-dev'
- 'pypy-3.7-v7.3.5'
# - 'pypy-3.8'
- 'pypy-3.7-v7.3.7'
- 'pypy-3.8-v7.3.7'

# Items in here will either be added to the build matrix (if not
# present), or add new keys to an existing matrix element if all the
# existing keys match.
#
# We support three optional keys: args (both build), args1 (first
# build), and args2 (second build).
# We support an optional keys: args, for cmake args
include:
# Just add a key
- runs-on: ubuntu-latest
Expand Down Expand Up @@ -122,15 +120,14 @@ jobs:
run: git clean -fdx

# Second build - C++17 mode and in a build directory
- name: Configure ${{ matrix.args2 }}
- name: Configure C++17
run: >
cmake -S . -B build2
-DPYBIND11_WERROR=ON
-DDOWNLOAD_CATCH=ON
-DDOWNLOAD_EIGEN=ON
-DCMAKE_CXX_STANDARD=17
${{ matrix.args }}
${{ matrix.args2 }}
- name: Build
run: cmake --build build2 -j 2
Expand Down
112 changes: 112 additions & 0 deletions .github/workflows/upstream.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@

name: Upstream

on:
workflow_dispatch:
pull_request:

concurrency:
group: upstream-${{ github.ref }}
cancel-in-progress: true

env:
PIP_ONLY_BINARY: numpy

jobs:
standard:
name: "🐍 3.11 dev • ubuntu-latest • x64"
runs-on: ubuntu-latest
if: "contains(github.event.pull_request.labels.*.name, 'python dev')"

steps:
- uses: actions/checkout@v2

- name: Setup Python 3.11
uses: actions/setup-python@v2
with:
python-version: "3.11-dev"

- name: Setup Boost (Linux)
if: runner.os == 'Linux'
run: sudo apt-get install libboost-dev

- name: Update CMake
uses: jwlawson/actions-setup-cmake@v1.11

- name: Prepare env
run: |
python -m pip install -r tests/requirements.txt
- name: Setup annotations on Linux
if: runner.os == 'Linux'
run: python -m pip install pytest-github-actions-annotate-failures

# First build - C++11 mode and inplace
- name: Configure C++11
run: >
cmake -S . -B .
-DPYBIND11_WERROR=ON
-DDOWNLOAD_CATCH=ON
-DDOWNLOAD_EIGEN=ON
-DCMAKE_CXX_STANDARD=11
- name: Build C++11
run: cmake --build . -j 2

- name: Python tests C++11
run: cmake --build . --target pytest -j 2

- name: C++11 tests
run: cmake --build . --target cpptest -j 2

- name: Interface test C++11
run: cmake --build . --target test_cmake_build

- name: Clean directory
run: git clean -fdx

# Second build - C++17 mode and in a build directory
- name: Configure C++17
run: >
cmake -S . -B build2
-DPYBIND11_WERROR=ON
-DDOWNLOAD_CATCH=ON
-DDOWNLOAD_EIGEN=ON
-DCMAKE_CXX_STANDARD=17
${{ matrix.args }}
${{ matrix.args2 }}
- name: Build
run: cmake --build build2 -j 2

- name: Python tests
run: cmake --build build2 --target pytest

- name: C++ tests
run: cmake --build build2 --target cpptest

# Third build - C++17 mode with unstable ABI
- name: Configure (unstable ABI)
run: >
cmake -S . -B build3
-DPYBIND11_WERROR=ON
-DDOWNLOAD_CATCH=ON
-DDOWNLOAD_EIGEN=ON
-DCMAKE_CXX_STANDARD=17
-DPYBIND11_INTERNALS_VERSION=10000000
"-DPYBIND11_TEST_OVERRIDE=test_call_policies.cpp;test_gil_scoped.cpp;test_thread.cpp"
${{ matrix.args }}
- name: Build (unstable ABI)
run: cmake --build build3 -j 2

- name: Python tests (unstable ABI)
run: cmake --build build3 --target pytest

- name: Interface test
run: cmake --build build2 --target test_cmake_build

# This makes sure the setup_helpers module can build packages using
# setuptools
- name: Setuptools helpers test
run: pytest tests/extra_setuptools
3 changes: 2 additions & 1 deletion include/pybind11/cast.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ struct type_caster<T, enable_if_t<std::is_arithmetic<T>::value && !is_std_char_t
return false;
} else {
handle src_or_index = src;
#if PY_VERSION_HEX < 0x03080000
// PyPy: 7.3.7's 3.8 does not implement PyLong_*'s __index__ calls.
#if PY_VERSION_HEX < 0x03080000 || defined(PYPY_VERSION)
object index;
if (!PYBIND11_LONG_CHECK(src.ptr())) { // So: index_check(src.ptr())
index = reinterpret_steal<object>(PyNumber_Index(src.ptr()));
Expand Down
4 changes: 2 additions & 2 deletions include/pybind11/eval.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
PYBIND11_NAMESPACE_BEGIN(detail)

inline void ensure_builtins_in_globals(object &global) {
#if PY_VERSION_HEX < 0x03080000
#if defined(PYPY_VERSION) || PY_VERSION_HEX < 0x03080000
// Running exec and eval on Python 2 and 3 adds `builtins` module under
// `__builtins__` key to globals if not yet present.
// Python 3.8 made PyRun_String behave similarly. Let's also do that for
// older versions, for consistency.
// older versions, for consistency. This was missing from PyPy3.8 7.3.7.
if (!global.contains("__builtins__"))
global["__builtins__"] = module_::import(PYBIND11_BUILTINS_MODULE);
#else
Expand Down
7 changes: 4 additions & 3 deletions include/pybind11/pybind11.h
Original file line number Diff line number Diff line change
Expand Up @@ -2365,16 +2365,17 @@ inline function get_type_override(const void *this_ptr, const type_info *this_ty

/* Don't call dispatch code if invoked from overridden function.
Unfortunately this doesn't work on PyPy. */
#if !defined(PYPY_VERSION)

#if !defined(PYPY_VERSION) && PY_VERSION_HEX < 0x030B0000
// TODO: Remove PyPy workaround for Python 3.11.
// Current API fails on 3.11 since co_varnames can be null.
#if PY_VERSION_HEX >= 0x03090000
PyFrameObject *frame = PyThreadState_GetFrame(PyThreadState_Get());
if (frame != nullptr) {
PyCodeObject *f_code = PyFrame_GetCode(frame);
// f_code is guaranteed to not be NULL
if ((std::string) str(f_code->co_name) == name && f_code->co_argcount > 0) {
PyObject* locals = PyEval_GetLocals();
if (locals != nullptr) {
if (locals != nullptr && f_code->co_varnames != nullptr) {
PyObject *self_caller = dict_getitem(
locals, PyTuple_GET_ITEM(f_code->co_varnames, 0)
);
Expand Down
2 changes: 1 addition & 1 deletion tests/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ numpy==1.16.6; python_version<"3.6" and sys_platform!="win32" and platform_pytho
numpy==1.19.0; platform_python_implementation=="PyPy" and sys_platform=="linux" and python_version=="3.6"
numpy==1.20.0; platform_python_implementation=="PyPy" and sys_platform=="linux" and python_version=="3.7"
numpy==1.19.3; platform_python_implementation!="PyPy" and python_version=="3.6"
numpy==1.21.3; platform_python_implementation!="PyPy" and python_version>="3.7"
numpy==1.21.3; platform_python_implementation!="PyPy" and python_version>="3.7" and python_version<"3.11"
py @ git+https://github.com/pytest-dev/py; python_version>="3.11"
pytest==4.6.9; python_version<"3.5"
pytest==6.1.2; python_version=="3.5"
Expand Down
4 changes: 4 additions & 0 deletions tests/test_buffers.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ def test_from_python():


# https://foss.heptapod.net/pypy/pypy/-/issues/2444
# TODO: fix on recent PyPy
@pytest.mark.xfail(
env.PYPY, reason="PyPy 7.3.7 doesn't clear this anymore", stict=False
)
def test_to_python():
mat = m.Matrix(5, 4)
assert memoryview(mat).shape == (5, 4)
Expand Down
7 changes: 5 additions & 2 deletions tests/test_builtin_casters.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,8 @@ def cant_convert(v):
assert noconvert(7) == 7
cant_convert(3.14159)
# TODO: Avoid DeprecationWarning in `PyLong_AsLong` (and similar)
if (3, 8) <= env.PY < (3, 10):
# TODO: PyPy 3.8 does not behave like CPython 3.8 here yet (7.3.7)
if (3, 8) <= env.PY < (3, 10) and env.CPYTHON:
with env.deprecated_call():
assert convert(Int()) == 42
else:
Expand Down Expand Up @@ -334,7 +335,9 @@ def require_implicit(v):

# The implicit conversion from np.float32 is undesirable but currently accepted.
# TODO: Avoid DeprecationWarning in `PyLong_AsLong` (and similar)
if (3, 8) <= env.PY < (3, 10):
# TODO: PyPy 3.8 does not behave like CPython 3.8 here yet (7.3.7)
# https://github.com/pybind/pybind11/issues/3408
if (3, 8) <= env.PY < (3, 10) and env.CPYTHON:
with env.deprecated_call():
assert convert(np.float32(3.14159)) == 3
else:
Expand Down
4 changes: 3 additions & 1 deletion tests/test_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import pytest

import env # noqa: F401
import env
import pybind11_cross_module_tests as cm
from pybind11_tests import exceptions as m

Expand Down Expand Up @@ -97,6 +97,8 @@ def ignore_pytest_unraisable_warning(f):
return f


# TODO: find out why this fails on PyPy, https://foss.heptapod.net/pypy/pypy/-/issues/3583
@pytest.mark.xfail(env.PYPY, reason="Failure on PyPy 3.8 (7.3.7)", strict=False)
@ignore_pytest_unraisable_warning
def test_python_alreadyset_in_destructor(monkeypatch, capsys):
hooked = False
Expand Down

0 comments on commit 72282f7

Please sign in to comment.