Skip to content

Commit 5635b0f

Browse files
clin1234ngoldbaumdavidhewittTpt
authored
Bump supported cpython version to 3.14 for testing (PyO3#4811)
* Add news item * Move news file * Fix version limit check in noxfile.py * Bump Python version for testing debug builds * 3.14 is available from GH's setup-python action * Bump maximum supported CPython version in pyo3-ffi * Rework PyASCIIObject and PyUnicodeObject to be compatible with 3.14 Due to python/cpython#128196, data types within `PyASCIIObject.state` have changed, resulting in test failures when building against 3.14. * Run `cargo fmt --all` * Actually add Py_3_14 as a legitimate macro When `rustc` is invoked, the macro is included with the `--check-cfg` flag, but not with the `--cfg` flag. This caused errors about duplicate definitions to spew out when building with stable Rust toolchains. * Revert "Actually add Py_3_14 as a legitimate macro" This reverts commit 5da57af. * Fix version macro placement for 3.14-specific getters and setters * Import 'c_ushort' only if compiling against CPython 3.14 or later * Add wrapper functions for the statically_allocated field * Remove unused libc::c_ushort * Add (hopefully) final version-specific macros * Port 3.14-specific 64-bit code of Py_INCREF * Don't expose PyDictObject.ma_version_tag when building against 3.14 or later * fix ffi-check on the GIL-enabled ABI * fix older pythons * fix ffi-check on older pythons * WIP: update for 3.14t * fix ffi-check on the free-threaded build * fix clippy * fix clippy on older python versions * fix cargo check on the MSRV * fix ffi-check on 3.13t * fix CI which is using 3.13.1 * fix copy/paste error in noxfile * update ffi bindings for the latest changes in 3.14 * update layout of refcnt field on gil-enabled build * delete unused HangThread struct * fix ffi-check on GIL-enabled build * Revert "delete unused HangThread struct" This reverts commit 3dd439d. * config-out HangThread * fix 3.13 ffi-check * fix debug python build error * fix graalpy build * Ignore DeprecationWarnings from the pytest_asyncio module in tests * Add abi3-py314 * fix free-threading issue in `test_coroutine` (PyO3#5069) * Introspection: add function signatures (PyO3#5025) * Introspection: add function signatures No annotations or explicit default values yet Fixes an issue related to object identifiers path * Better default value * Refine arguments struct * Introduce VariableLengthArgument * Adds pyfunctions tests * Adds some serialization tests * respond to david's code review * add comment and fix test failure * fix check-feature-powerset * fix clippy * fix wasip1 clippy * fix 32 bit python 3.14 bug * mark test-py step continue-on-error for dev python builds * use github issue URL * run ffi-check before running tests * fix ffi-check for 3.14.0a7 --------- Co-authored-by: Nathan Goldbaum <[email protected]> Co-authored-by: David Hewitt <[email protected]> Co-authored-by: Thomas Tanon <[email protected]>
1 parent 923867c commit 5635b0f

File tree

25 files changed

+860
-345
lines changed

25 files changed

+860
-345
lines changed

.github/workflows/build.yml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,11 @@ jobs:
132132
name: Build PyPy (abi3-py39)
133133
run: cargo build --lib --tests --no-default-features --features "multiple-pymethods abi3-py39 full $MAYBE_NIGHTLY"
134134

135+
- name: Run pyo3-ffi-check
136+
# pypy 3.9 on windows is not PEP 3123 compliant, nor is graalpy
137+
if: ${{ endsWith(inputs.python-version, '-dev') || (steps.ffi-changes.outputs.changed == 'true' && inputs.rust == 'stable' && !startsWith(inputs.python-version, 'graalpy') && !(inputs.python-version == 'pypy3.9' && contains(inputs.os, 'windows'))) }}
138+
run: nox -s ffi-check
139+
135140
# Run tests (except on PyPy, because no embedding API).
136141
- if: ${{ !startsWith(inputs.python-version, 'pypy') && !startsWith(inputs.python-version, 'graalpy') }}
137142
name: Test
@@ -161,6 +166,7 @@ jobs:
161166
- name: Test python examples and tests
162167
shell: bash
163168
run: nox -s test-py
169+
continue-on-error: ${{ endsWith(inputs.python-version, '-dev') }}
164170
env:
165171
CARGO_TARGET_DIR: ${{ github.workspace }}/target
166172

@@ -177,11 +183,6 @@ jobs:
177183
- '.github/workflows/ci.yml'
178184
- '.github/workflows/build.yml'
179185
180-
- name: Run pyo3-ffi-check
181-
# pypy 3.9 on windows is not PEP 3123 compliant, nor is graalpy
182-
if: ${{ endsWith(inputs.python-version, '-dev') || (steps.ffi-changes.outputs.changed == 'true' && inputs.rust == 'stable' && !startsWith(inputs.python-version, 'graalpy') && !(inputs.python-version == 'pypy3.9' && contains(inputs.os, 'windows'))) }}
183-
run: nox -s ffi-check
184-
185186
- if: ${{ github.event_name != 'merge_group' }}
186187
name: Generate coverage report
187188
run: cargo llvm-cov

.github/workflows/ci.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,8 @@ jobs:
264264
"3.12",
265265
"3.13",
266266
"3.13t",
267+
"3.14-dev",
268+
"3.14t-dev",
267269
"pypy3.9",
268270
"pypy3.10",
269271
"pypy3.11",
@@ -528,8 +530,8 @@ jobs:
528530
components: rust-src
529531
- name: Install python3 standalone debug build with nox
530532
run: |
531-
PBS_RELEASE="20241016"
532-
PBS_PYTHON_VERSION="3.13.0"
533+
PBS_RELEASE="20241219"
534+
PBS_PYTHON_VERSION="3.13.1"
533535
PBS_ARCHIVE="cpython-${PBS_PYTHON_VERSION}+${PBS_RELEASE}-x86_64-unknown-linux-gnu-debug-full.tar.zst"
534536
wget "https://github.com/indygreg/python-build-standalone/releases/download/${PBS_RELEASE}/${PBS_ARCHIVE}"
535537
tar -I zstd -xf "${PBS_ARCHIVE}"

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ abi3-py39 = ["abi3-py310", "pyo3-build-config/abi3-py39", "pyo3-ffi/abi3-py39"]
103103
abi3-py310 = ["abi3-py311", "pyo3-build-config/abi3-py310", "pyo3-ffi/abi3-py310"]
104104
abi3-py311 = ["abi3-py312", "pyo3-build-config/abi3-py311", "pyo3-ffi/abi3-py311"]
105105
abi3-py312 = ["abi3-py313", "pyo3-build-config/abi3-py312", "pyo3-ffi/abi3-py312"]
106-
abi3-py313 = ["abi3", "pyo3-build-config/abi3-py313", "pyo3-ffi/abi3-py313"]
106+
abi3-py313 = ["abi3-py314", "pyo3-build-config/abi3-py313", "pyo3-ffi/abi3-py313"]
107+
abi3-py314 = ["abi3", "pyo3-build-config/abi3-py314", "pyo3-ffi/abi3-py314"]
107108

108109
# Automatically generates `python3.dll` import libraries for Windows targets.
109110
generate-import-lib = ["pyo3-ffi/generate-import-lib"]

newsfragments/4811.fixed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Bump supported cpython version to 3.14 for testing

noxfile.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -708,11 +708,11 @@ def test_version_limits(session: nox.Session):
708708
config_file.set("CPython", "3.6")
709709
_run_cargo(session, "check", env=env, expect_error=True)
710710

711-
assert "3.14" not in PY_VERSIONS
712-
config_file.set("CPython", "3.14")
711+
assert "3.15" not in PY_VERSIONS
712+
config_file.set("CPython", "3.15")
713713
_run_cargo(session, "check", env=env, expect_error=True)
714714

715-
# 3.14 CPython should build with forward compatibility
715+
# 3.15 CPython should build with forward compatibility
716716
env["PYO3_USE_ABI3_FORWARD_COMPATIBILITY"] = "1"
717717
_run_cargo(session, "check", env=env)
718718

pyo3-build-config/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ abi3-py39 = ["abi3-py310"]
3838
abi3-py310 = ["abi3-py311"]
3939
abi3-py311 = ["abi3-py312"]
4040
abi3-py312 = ["abi3-py313"]
41-
abi3-py313 = ["abi3"]
41+
abi3-py313 = ["abi3-py314"]
42+
abi3-py314 = ["abi3"]
4243

4344
[package.metadata.docs.rs]
4445
features = ["resolve-config"]

pyo3-ffi-check/build.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,24 @@
11
use std::env;
22
use std::path::PathBuf;
33

4+
#[derive(Debug)]
5+
struct ParseCallbacks;
6+
7+
impl bindgen::callbacks::ParseCallbacks for ParseCallbacks {
8+
// these are anonymous fields and structs in CPython that we needed to
9+
// invent names for. Bindgen seems to generate stable names, so we remap the
10+
// automatically generated names to the names we invented in the FFI
11+
fn item_name(&self, _original_item_name: &str) -> Option<String> {
12+
if _original_item_name == "_object__bindgen_ty_1__bindgen_ty_1" {
13+
Some("PyObjectObFlagsAndRefcnt".into())
14+
} else if _original_item_name == "_object__bindgen_ty_1" {
15+
Some("PyObjectObRefcnt".into())
16+
} else {
17+
None
18+
}
19+
}
20+
}
21+
422
fn main() {
523
let config = pyo3_build_config::get();
624
let python_include_dir = config
@@ -29,6 +47,7 @@ fn main() {
2947
.header("wrapper.h")
3048
.clang_args(clang_args)
3149
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
50+
.parse_callbacks(Box::new(ParseCallbacks))
3251
// blocklist some values which apparently have conflicting definitions on unix
3352
.blocklist_item("FP_NORMAL")
3453
.blocklist_item("FP_SUBNORMAL")

pyo3-ffi/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ abi3-py39 = ["abi3-py310", "pyo3-build-config/abi3-py39"]
3434
abi3-py310 = ["abi3-py311", "pyo3-build-config/abi3-py310"]
3535
abi3-py311 = ["abi3-py312", "pyo3-build-config/abi3-py311"]
3636
abi3-py312 = ["abi3-py313", "pyo3-build-config/abi3-py312"]
37-
abi3-py313 = ["abi3", "pyo3-build-config/abi3-py313"]
37+
abi3-py313 = ["abi3-py314", "pyo3-build-config/abi3-py313"]
38+
abi3-py314 = ["abi3", "pyo3-build-config/abi3-py314"]
3839

3940
# Automatically generates `python3.dll` import libraries for Windows targets.
4041
generate-import-lib = ["pyo3-build-config/python3-dll-a"]
@@ -50,7 +51,7 @@ workspace = true
5051

5152
[package.metadata.cpython]
5253
min-version = "3.7"
53-
max-version = "3.13" # inclusive
54+
max-version = "3.14" # inclusive
5455

5556
[package.metadata.pypy]
5657
min-version = "3.9"

pyo3-ffi/build.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const SUPPORTED_VERSIONS_CPYTHON: SupportedVersions = SupportedVersions {
1717
min: PythonVersion { major: 3, minor: 7 },
1818
max: PythonVersion {
1919
major: 3,
20-
minor: 13,
20+
minor: 14,
2121
},
2222
};
2323

pyo3-ffi/src/abstract_.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub unsafe fn PyObject_DelAttr(o: *mut PyObject, attr_name: *mut PyObject) -> c_
2525
extern "C" {
2626
#[cfg(all(
2727
not(PyPy),
28+
not(GraalPy),
2829
any(Py_3_10, all(not(Py_LIMITED_API), Py_3_9)) // Added to python in 3.9 but to limited API in 3.10
2930
))]
3031
#[cfg_attr(PyPy, link_name = "PyPyObject_CallNoArgs")]

pyo3-ffi/src/cpython/dictobject.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ pub struct PyDictObject {
1717
Py_3_12,
1818
deprecated(note = "Deprecated in Python 3.12 and will be removed in the future.")
1919
)]
20+
#[cfg(not(Py_3_14))]
2021
pub ma_version_tag: u64,
22+
#[cfg(Py_3_14)]
23+
_ma_watcher_tag: u64,
2124
pub ma_keys: *mut PyDictKeysObject,
2225
#[cfg(not(Py_3_11))]
2326
pub ma_values: *mut *mut PyObject,

pyo3-ffi/src/cpython/funcobject.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ pub struct PyFunctionObject {
4141
pub func_weakreflist: *mut PyObject,
4242
pub func_module: *mut PyObject,
4343
pub func_annotations: *mut PyObject,
44+
#[cfg(Py_3_14)]
45+
pub func_annotate: *mut PyObject,
4446
#[cfg(Py_3_12)]
4547
pub func_typeparams: *mut PyObject,
4648
pub vectorcall: Option<crate::vectorcallfunc>,

pyo3-ffi/src/cpython/genobject.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use crate::object::*;
22
use crate::PyFrameObject;
3-
#[cfg(all(Py_3_11, not(any(PyPy, GraalPy))))]
3+
#[cfg(all(Py_3_11, not(any(PyPy, GraalPy, Py_3_14))))]
44
use std::os::raw::c_char;
55
use std::os::raw::c_int;
66
use std::ptr::addr_of_mut;
77

8-
#[cfg(not(any(PyPy, GraalPy)))]
8+
#[cfg(not(any(PyPy, GraalPy, Py_3_14)))]
99
#[repr(C)]
1010
pub struct PyGenObject {
1111
pub ob_base: PyObject,
@@ -33,6 +33,9 @@ pub struct PyGenObject {
3333
pub gi_iframe: [*mut PyObject; 1],
3434
}
3535

36+
#[cfg(all(Py_3_14, not(any(PyPy, GraalPy))))]
37+
opaque_struct!(pub PyGenObject);
38+
3639
#[cfg_attr(windows, link(name = "pythonXY"))]
3740
extern "C" {
3841
pub static mut PyGen_Type: PyTypeObject;

pyo3-ffi/src/cpython/initconfig.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ pub struct PyConfig {
9393
pub tracemalloc: c_int,
9494
#[cfg(Py_3_12)]
9595
pub perf_profiling: c_int,
96+
#[cfg(Py_3_14)]
97+
pub remote_debug: c_int,
9698
pub import_time: c_int,
9799
#[cfg(Py_3_11)]
98100
pub code_debug_ranges: c_int,
@@ -141,10 +143,19 @@ pub struct PyConfig {
141143
pub safe_path: c_int,
142144
#[cfg(Py_3_12)]
143145
pub int_max_str_digits: c_int,
146+
// TODO: uncomment for 3.14.0b1
147+
// #[cfg(Py_3_14)]
148+
// pub thread_inherit_context: c_int,
149+
// #[cfg(Py_3_14)]
150+
// pub context_aware_warnings: c_int,
151+
#[cfg(all(Py_3_14, target_os = "macos"))]
152+
pub use_system_logger: c_int,
144153
#[cfg(Py_3_13)]
145154
pub cpu_count: c_int,
146155
#[cfg(Py_GIL_DISABLED)]
147156
pub enable_gil: c_int,
157+
#[cfg(all(Py_3_14, Py_GIL_DISABLED))]
158+
pub tlbc_enabled: c_int,
148159
pub pathconfig_warnings: c_int,
149160
#[cfg(Py_3_10)]
150161
pub program_name: *mut wchar_t,

pyo3-ffi/src/cpython/object.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,8 +312,12 @@ pub struct PyHeapTypeObject {
312312
pub ht_module: *mut object::PyObject,
313313
#[cfg(all(Py_3_11, not(PyPy)))]
314314
_ht_tpname: *mut c_char,
315+
#[cfg(Py_3_14)]
316+
pub ht_token: *mut c_void,
315317
#[cfg(all(Py_3_11, not(PyPy)))]
316318
_spec_cache: _specialization_cache,
319+
#[cfg(all(Py_GIL_DISABLED, Py_3_14))]
320+
pub unique_id: Py_ssize_t,
317321
}
318322

319323
impl Default for PyHeapTypeObject {

pyo3-ffi/src/cpython/pyerrors.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ pub struct PySyntaxErrorObject {
4646
pub end_offset: *mut PyObject,
4747
pub text: *mut PyObject,
4848
pub print_file_and_line: *mut PyObject,
49+
// TODO: uncomment for 3.14.0b1
50+
// #[cfg(Py_3_14)]
51+
// pub metadata: *mut PyObject,
4952
}
5053

5154
#[cfg(not(any(PyPy, GraalPy)))]

pyo3-ffi/src/cpython/tupleobject.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
use crate::object::*;
2+
#[cfg(Py_3_14)]
3+
use crate::pyport::Py_hash_t;
24
#[cfg(not(PyPy))]
35
use crate::pyport::Py_ssize_t;
46

57
#[repr(C)]
68
pub struct PyTupleObject {
79
pub ob_base: PyVarObject,
10+
#[cfg(Py_3_14)]
11+
pub ob_hash: Py_hash_t,
812
pub ob_item: [*mut PyObject; 1],
913
}
1014

0 commit comments

Comments
 (0)