Skip to content

Commit e7e2c79

Browse files
authored
fix: improve support for Python 3.11-dev (#3368)
* ci: support Python 3.11-dev Also update 3.10 to final, better PyPy usage * fix: use PyFrame_GetCode on Python 3.9+ * ci: some bitiness of pypy not supported on win * chore: update CMake support to 3.22rc1 to quiet warning * fix: use dev version of py to fix Py 3.11 * tests: print proper Eigen version * ci: include pypy2, not sure why * ci: avoid running on Python 3.11 for now * ci: fix runs * ci: simpler PyPy usage, drop unmaintained scipy + pypy index * ci: only binary numpy, wait on pypy 3.8 * refactor: address review
1 parent c2d3e22 commit e7e2c79

File tree

9 files changed

+105
-57
lines changed

9 files changed

+105
-57
lines changed

.github/workflows/ci.yml

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ concurrency:
1313
group: test-${{ github.ref }}
1414
cancel-in-progress: true
1515

16+
env:
17+
PIP_ONLY_BINARY: numpy
18+
1619
jobs:
1720
# This is the "main" test suite, which tests a large number of different
1821
# versions of default compilers and Python versions in GitHub Actions.
@@ -22,13 +25,14 @@ jobs:
2225
matrix:
2326
runs-on: [ubuntu-latest, windows-latest, macos-latest]
2427
python:
25-
- 2.7
26-
- 3.5
27-
- 3.6
28-
- 3.9
29-
- 3.10-dev
30-
- pypy2
31-
- pypy3
28+
- '2.7'
29+
- '3.5'
30+
- '3.6'
31+
- '3.9'
32+
- '3.10'
33+
# - '3.11-dev'
34+
- 'pypy-3.7-v7.3.5'
35+
# - 'pypy-3.8'
3236

3337
# Items in here will either be added to the build matrix (if not
3438
# present), or add new keys to an existing matrix element if all the
@@ -46,18 +50,8 @@ jobs:
4650
python: 3.6
4751
args: >
4852
-DPYBIND11_FINDPYTHON=ON
49-
50-
# These items will be removed from the build matrix, keys must match.
51-
exclude:
52-
# Currently 32bit only, and we build 64bit
53-
- runs-on: windows-latest
54-
python: pypy2
55-
- runs-on: windows-latest
56-
python: pypy3
57-
58-
# TODO: PyPy2 7.3.3 segfaults, while 7.3.2 was fine.
59-
- runs-on: ubuntu-latest
60-
python: pypy2
53+
- runs-on: macos-latest
54+
python: pypy-2.7
6155

6256
name: "🐍 ${{ matrix.python }} • ${{ matrix.runs-on }} • x64 ${{ matrix.args }}"
6357
runs-on: ${{ matrix.runs-on }}
@@ -93,7 +87,8 @@ jobs:
9387
key: ${{ runner.os }}-pip-${{ matrix.python }}-x64-${{ hashFiles('tests/requirements.txt') }}
9488

9589
- name: Prepare env
96-
run: python -m pip install -r tests/requirements.txt --prefer-binary
90+
run: |
91+
python -m pip install -r tests/requirements.txt
9792
9893
- name: Setup annotations on Linux
9994
if: runner.os == 'Linux'
@@ -117,7 +112,7 @@ jobs:
117112

118113
- name: C++11 tests
119114
# TODO: Figure out how to load the DLL on Python 3.8+
120-
if: "!(runner.os == 'Windows' && (matrix.python == 3.8 || matrix.python == 3.9 || matrix.python == '3.10-dev'))"
115+
if: "!(runner.os == 'Windows' && (matrix.python == 3.8 || matrix.python == 3.9 || matrix.python == '3.10' || matrix.python == '3.11-dev' || matrix.python == 'pypy-3.8'))"
121116
run: cmake --build . --target cpptest -j 2
122117

123118
- name: Interface test C++11
@@ -145,7 +140,7 @@ jobs:
145140

146141
- name: C++ tests
147142
# TODO: Figure out how to load the DLL on Python 3.8+
148-
if: "!(runner.os == 'Windows' && (matrix.python == 3.8 || matrix.python == 3.9 || matrix.python == '3.10-dev'))"
143+
if: "!(runner.os == 'Windows' && (matrix.python == 3.8 || matrix.python == 3.9 || matrix.python == '3.10' || matrix.python == '3.11-dev' || matrix.python == 'pypy-3.8'))"
149144
run: cmake --build build2 --target cpptest
150145

151146
# Third build - C++17 mode with unstable ABI
@@ -196,11 +191,12 @@ jobs:
196191
fail-fast: false
197192
matrix:
198193
include:
199-
- python-version: 3.9
194+
# TODO: Fails on 3.10, investigate
195+
- python-version: "3.9"
200196
python-debug: true
201197
valgrind: true
202-
- python-version: 3.10-dev
203-
python-debug: false
198+
# - python-version: "3.11-dev"
199+
# python-debug: false
204200

205201
name: "🐍 ${{ matrix.python-version }}${{ matrix.python-debug && '-dbg' || '' }} (deadsnakes)${{ matrix.valgrind && ' • Valgrind' || '' }} • x64"
206202
runs-on: ubuntu-latest
@@ -244,7 +240,8 @@ jobs:
244240
sudo apt-get install libc6-dbg # Needed by Valgrind
245241
246242
- name: Prepare env
247-
run: python -m pip install -r tests/requirements.txt --prefer-binary
243+
run: |
244+
python -m pip install -r tests/requirements.txt
248245
249246
- name: Configure
250247
run: >
@@ -521,7 +518,7 @@ jobs:
521518
- name: Install dependencies
522519
run: |
523520
set +e; source /opt/intel/oneapi/setvars.sh; set -e
524-
python3 -m pip install -r tests/requirements.txt --prefer-binary
521+
python3 -m pip install -r tests/requirements.txt
525522
526523
- name: Configure C++11
527524
run: |
@@ -612,7 +609,8 @@ jobs:
612609
run: python3 -m pip install --upgrade pip
613610

614611
- name: Install dependencies
615-
run: python3 -m pip install cmake -r tests/requirements.txt --prefer-binary
612+
run: |
613+
python3 -m pip install cmake -r tests/requirements.txt
616614
617615
- name: VAR_BUILD_TYPE 7
618616
if: matrix.centos == 7
@@ -739,8 +737,7 @@ jobs:
739737
- 3.7
740738
- 3.8
741739
- 3.9
742-
- pypy3
743-
# TODO: fix hang on pypy2
740+
- pypy-3.6
744741

745742
include:
746743
- python: 3.9
@@ -769,7 +766,8 @@ jobs:
769766
arch: x86
770767

771768
- name: Prepare env
772-
run: python -m pip install -r tests/requirements.txt --prefer-binary
769+
run: |
770+
python -m pip install -r tests/requirements.txt
773771
774772
# First build - C++11 mode and inplace
775773
- name: Configure ${{ matrix.args }}
@@ -815,7 +813,8 @@ jobs:
815813
toolset: 14.0
816814

817815
- name: Prepare env
818-
run: python -m pip install -r tests/requirements.txt --prefer-binary
816+
run: |
817+
python -m pip install -r tests/requirements.txt
819818
820819
# First build - C++11 mode and inplace
821820
- name: Configure
@@ -868,7 +867,8 @@ jobs:
868867
uses: jwlawson/[email protected]
869868

870869
- name: Prepare env
871-
run: python -m pip install -r tests/requirements.txt --prefer-binary
870+
run: |
871+
python -m pip install -r tests/requirements.txt
872872
873873
# First build - C++11 mode and inplace
874874
- name: Configure

.github/workflows/pip.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ on:
1212
types:
1313
- published
1414

15+
env:
16+
PIP_ONLY_BINARY: numpy
17+
1518
jobs:
1619
# This builds the sdists and wheels and makes sure the files are exactly as
1720
# expected. Using Windows and Python 2.7, since that is often the most
@@ -29,7 +32,8 @@ jobs:
2932
python-version: 2.7
3033

3134
- name: Prepare env
32-
run: python -m pip install -r tests/requirements.txt --prefer-binary
35+
run: |
36+
python -m pip install -r tests/requirements.txt
3337
3438
- name: Python Packaging tests
3539
run: pytest tests/extra_python_package/
@@ -50,7 +54,8 @@ jobs:
5054
python-version: 3.8
5155

5256
- name: Prepare env
53-
run: python -m pip install -r tests/requirements.txt build twine --prefer-binary
57+
run: |
58+
python -m pip install -r tests/requirements.txt build twine
5459
5560
- name: Python Packaging tests
5661
run: pytest tests/extra_python_package/

CMakeLists.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77

88
cmake_minimum_required(VERSION 3.4)
99

10-
# The `cmake_minimum_required(VERSION 3.4...3.21)` syntax does not work with
10+
# The `cmake_minimum_required(VERSION 3.4...3.22)` syntax does not work with
1111
# some versions of VS that have a patched CMake 3.11. This forces us to emulate
1212
# the behavior using the following workaround:
13-
if(${CMAKE_VERSION} VERSION_LESS 3.21)
13+
if(${CMAKE_VERSION} VERSION_LESS 3.22)
1414
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
1515
else()
16-
cmake_policy(VERSION 3.21)
16+
cmake_policy(VERSION 3.22)
1717
endif()
1818

1919
# Extract project version from source

include/pybind11/detail/type_caster_base.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -468,12 +468,19 @@ PYBIND11_NOINLINE std::string error_string() {
468468
PyFrameObject *frame = trace->tb_frame;
469469
errorString += "\n\nAt:\n";
470470
while (frame) {
471+
#if PY_VERSION_HEX >= 0x03090000
472+
PyCodeObject *f_code = PyFrame_GetCode(frame);
473+
#else
474+
PyCodeObject *f_code = frame->f_code;
475+
Py_INCREF(f_code);
476+
#endif
471477
int lineno = PyFrame_GetLineNumber(frame);
472478
errorString +=
473-
" " + handle(frame->f_code->co_filename).cast<std::string>() +
479+
" " + handle(f_code->co_filename).cast<std::string>() +
474480
"(" + std::to_string(lineno) + "): " +
475-
handle(frame->f_code->co_name).cast<std::string>() + "\n";
481+
handle(f_code->co_name).cast<std::string>() + "\n";
476482
frame = frame->f_back;
483+
Py_DECREF(f_code);
477484
}
478485
}
479486
#endif

include/pybind11/pybind11.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2335,6 +2335,29 @@ inline function get_type_override(const void *this_ptr, const type_info *this_ty
23352335
/* Don't call dispatch code if invoked from overridden function.
23362336
Unfortunately this doesn't work on PyPy. */
23372337
#if !defined(PYPY_VERSION)
2338+
2339+
#if PY_VERSION_HEX >= 0x03090000
2340+
PyFrameObject *frame = PyThreadState_GetFrame(PyThreadState_Get());
2341+
if (frame != nullptr) {
2342+
PyCodeObject *f_code = PyFrame_GetCode(frame);
2343+
// f_code is guaranteed to not be NULL
2344+
if ((std::string) str(f_code->co_name) == name && f_code->co_argcount > 0) {
2345+
PyObject* locals = PyEval_GetLocals();
2346+
if (locals != nullptr) {
2347+
PyObject *self_caller = dict_getitem(
2348+
locals, PyTuple_GET_ITEM(f_code->co_varnames, 0)
2349+
);
2350+
if (self_caller == self.ptr()) {
2351+
Py_DECREF(f_code);
2352+
Py_DECREF(frame);
2353+
return function();
2354+
}
2355+
}
2356+
}
2357+
Py_DECREF(f_code);
2358+
Py_DECREF(frame);
2359+
}
2360+
#else
23382361
PyFrameObject *frame = PyThreadState_Get()->frame;
23392362
if (frame != nullptr && (std::string) str(frame->f_code->co_name) == name
23402363
&& frame->f_code->co_argcount > 0) {
@@ -2344,6 +2367,8 @@ inline function get_type_override(const void *this_ptr, const type_info *this_ty
23442367
if (self_caller == self.ptr())
23452368
return function();
23462369
}
2370+
#endif
2371+
23472372
#else
23482373
/* PyPy currently doesn't provide a detailed cpyext emulation of
23492374
frame objects, so we have to emulate this using Python. This

noxfile.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
nox.options.sessions = ["lint", "tests", "tests_packaging"]
44

5-
PYTHON_VERISONS = ["2.7", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10"]
5+
PYTHON_VERISONS = ["2.7", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11"]
66

77

88
@nox.session(reuse_venv=True)
@@ -20,7 +20,8 @@ def tests(session: nox.Session) -> None:
2020
Run the tests (requires a compiler).
2121
"""
2222
tmpdir = session.create_tmp()
23-
session.install("pytest", "cmake")
23+
session.install("cmake")
24+
session.install("-r", "tests/requirements.txt")
2425
session.run(
2526
"cmake",
2627
"-S",

tests/CMakeLists.txt

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,14 @@ set(PYBIND11_CROSS_MODULE_GIL_TESTS test_gil_scoped.py)
174174
set(PYBIND11_EIGEN_REPO
175175
"https://gitlab.com/libeigen/eigen.git"
176176
CACHE STRING "Eigen repository to use for tests")
177-
# This hash is for 3.4.0, using a hash for security reasons
178-
set(PYBIND11_EIGEN_VERSION
179-
"929bc0e191d0927b1735b9a1ddc0e8b77e3a25ec"
180-
CACHE STRING "Eigen version to use for tests")
177+
# Always use a hash for reconfigure speed and security reasons
178+
# Include the version number for pretty printing (keep in sync)
179+
set(PYBIND11_EIGEN_VERSION_AND_HASH
180+
"3.4.0;929bc0e191d0927b1735b9a1ddc0e8b77e3a25ec"
181+
CACHE STRING "Eigen version to use for tests, format: VERSION;HASH")
182+
183+
list(GET PYBIND11_EIGEN_VERSION_AND_HASH 0 PYBIND11_EIGEN_VERSION_STRING)
184+
list(GET PYBIND11_EIGEN_VERSION_AND_HASH 1 PYBIND11_EIGEN_VERSION_HASH)
181185

182186
# Check if Eigen is available; if not, remove from PYBIND11_TEST_FILES (but
183187
# keep it in PYBIND11_PYTEST_FILES, so that we get the "eigen is not installed"
@@ -196,16 +200,22 @@ if(PYBIND11_TEST_FILES_EIGEN_I GREATER -1)
196200
FetchContent_Declare(
197201
eigen
198202
GIT_REPOSITORY "${PYBIND11_EIGEN_REPO}"
199-
GIT_TAG "${PYBIND11_EIGEN_VERSION}")
203+
GIT_TAG "${PYBIND11_EIGEN_VERSION_HASH}")
200204

201205
FetchContent_GetProperties(eigen)
202206
if(NOT eigen_POPULATED)
203-
message(STATUS "Downloading Eigen")
207+
message(
208+
STATUS
209+
"Downloading Eigen ${PYBIND11_EIGEN_VERSION_STRING} (${PYBIND11_EIGEN_VERSION_HASH}) from ${PYBIND11_EIGEN_REPO}"
210+
)
204211
FetchContent_Populate(eigen)
205212
endif()
206213

207214
set(EIGEN3_INCLUDE_DIR ${eigen_SOURCE_DIR})
208215
set(EIGEN3_FOUND TRUE)
216+
# When getting locally, the version is not visible from a superprojet,
217+
# so just force it.
218+
set(EIGEN3_VERSION "${PYBIND11_EIGEN_VERSION_STRING}")
209219

210220
else()
211221
find_package(Eigen3 3.2.7 QUIET CONFIG)

tests/requirements.txt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
--extra-index-url https://antocuni.github.io/pypy-wheels/manylinux2010/
2-
numpy==1.16.6; python_version<"3.6" and sys_platform!="win32"
3-
numpy==1.18.0; platform_python_implementation=="PyPy" and sys_platform=="darwin" and python_version>="3.6"
4-
numpy==1.19.3; (platform_python_implementation!="PyPy" or sys_platform=="linux") and python_version=="3.6"
5-
numpy==1.21.2; (platform_python_implementation!="PyPy" or sys_platform=="linux") and python_version>="3.7" and python_version<"3.10"
6-
numpy==1.21.2; platform_python_implementation!="PyPy" and sys_platform=="linux" and python_version=="3.10"
1+
numpy==1.16.6; python_version<"3.6" and sys_platform!="win32" and platform_python_implementation!="PyPy"
2+
numpy==1.19.0; platform_python_implementation=="PyPy" and sys_platform=="linux" and python_version=="3.6"
3+
numpy==1.20.0; platform_python_implementation=="PyPy" and sys_platform=="linux" and python_version=="3.7"
4+
numpy==1.19.3; platform_python_implementation!="PyPy" and python_version=="3.6"
5+
numpy==1.21.3; platform_python_implementation!="PyPy" and python_version>="3.7"
6+
py @ git+https://github.com/pytest-dev/py; python_version>="3.11"
77
pytest==4.6.9; python_version<"3.5"
88
pytest==6.1.2; python_version=="3.5"
99
pytest==6.2.4; python_version>="3.6"
1010
pytest-timeout
11-
scipy==1.2.3; (platform_python_implementation!="PyPy" or sys_platform=="linux") and python_version<"3.6"
12-
scipy==1.5.4; (platform_python_implementation!="PyPy" or sys_platform=="linux") and python_version>="3.6" and python_version<"3.10"
11+
scipy==1.2.3; platform_python_implementation!="PyPy" and python_version<"3.6"
12+
scipy==1.5.4; platform_python_implementation!="PyPy" and python_version>="3.6" and python_version<"3.10"

tools/pybind11Tools.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ endif()
3838

3939
# A user can set versions manually too
4040
set(Python_ADDITIONAL_VERSIONS
41-
"3.10;3.9;3.8;3.7;3.6;3.5;3.4"
41+
"3.11;3.10;3.9;3.8;3.7;3.6;3.5;3.4"
4242
CACHE INTERNAL "")
4343

4444
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")

0 commit comments

Comments
 (0)