Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drop support for PyPy 3.7 and 3.8 #4582

Merged
merged 3 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ on:

jobs:
build:
continue-on-error: ${{ endsWith(inputs.python-version, '-dev') || contains(fromJSON('["3.7", "pypy3.7"]'), inputs.python-version) || inputs.rust == 'beta' || inputs.rust == 'nightly' }}
continue-on-error: ${{ endsWith(inputs.python-version, '-dev') || contains(fromJSON('["3.7", "3.8"]'), inputs.python-version) || contains(fromJSON('["beta", "nightly"]'), inputs.rust) }}
runs-on: ${{ inputs.os }}
if: ${{ !(startsWith(inputs.python-version, 'graalpy') && startsWith(inputs.os, 'windows')) }}
steps:
Expand Down Expand Up @@ -95,8 +95,8 @@ jobs:
run: cargo build --lib --tests --no-default-features --features "multiple-pymethods full $MAYBE_NIGHTLY"

- if: ${{ startsWith(inputs.python-version, 'pypy') }}
name: Build PyPy (abi3-py37)
run: cargo build --lib --tests --no-default-features --features "multiple-pymethods abi3-py37 full $MAYBE_NIGHTLY"
name: Build PyPy (abi3-py39)
run: cargo build --lib --tests --no-default-features --features "multiple-pymethods abi3-py39 full $MAYBE_NIGHTLY"

# Run tests (except on PyPy, because no embedding API).
- if: ${{ !startsWith(inputs.python-version, 'pypy') && !startsWith(inputs.python-version, 'graalpy') }}
Expand Down Expand Up @@ -131,8 +131,7 @@ jobs:
CARGO_TARGET_DIR: ${{ github.workspace }}/target

- uses: dorny/paths-filter@v3
# pypy 3.7 and 3.8 are not PEP 3123 compliant so fail checks here
if: ${{ inputs.rust == 'stable' && inputs.python-version != 'pypy3.7' && inputs.python-version != 'pypy3.8' && !startsWith(inputs.python-version, 'graalpy') }}
if: ${{ inputs.rust == 'stable' && !startsWith(inputs.python-version, 'graalpy') }}
id: ffi-changes
with:
base: ${{ github.event.pull_request.base.ref || github.event.merge_group.base_ref }}
Expand All @@ -145,9 +144,8 @@ jobs:
- '.github/workflows/build.yml'

- name: Run pyo3-ffi-check
# pypy 3.7 and 3.8 are not PEP 3123 compliant so fail checks here, nor
# is pypy 3.9 on windows
if: ${{ endsWith(inputs.python-version, '-dev') || (steps.ffi-changes.outputs.changed == 'true' && inputs.rust == 'stable' && inputs.python-version != 'pypy3.7' && inputs.python-version != 'pypy3.8' && !startsWith(inputs.python-version, 'graalpy') && !(inputs.python-version == 'pypy3.9' && contains(inputs.os, 'windows'))) }}
# pypy 3.9 on windows is not PEP 3123 compliant, nor is graalpy
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'))) }}
run: nox -s ffi-check

env:
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,6 @@ jobs:
"3.11",
"3.12",
"3.13-dev",
"pypy3.7",
"pypy3.8",
"pypy3.9",
"pypy3.10",
"graalpy24.0",
Expand Down
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@

## Usage

PyO3 supports the following software versions:
- Python 3.7 and up (CPython, PyPy, and GraalPy)
- Rust 1.63 and up
Requires Rust 1.63 or greater.

PyO3 supports the following Python distributions:
- CPython 3.7 or greater
- PyPy 7.3 (Python 3.9+)
- GraalPy 24.0 or greater (Python 3.10+)

You can use PyO3 to write a native Python module in Rust, or to embed Python in a Rust binary. The following sections explain each of these in turn.

Expand Down
4 changes: 2 additions & 2 deletions guide/src/building-and-distribution.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ Rather than using just the `.so` or `.pyd` extension suggested above (depending
# CPython 3.10 on macOS
.cpython-310-darwin.so

# PyPy 7.3 (Python 3.8) on Linux
# PyPy 7.3 (Python 3.9) on Linux
$ python -c 'import sysconfig; print(sysconfig.get_config_var("EXT_SUFFIX"))'
.pypy38-pp73-x86_64-linux-gnu.so
.pypy39-pp73-x86_64-linux-gnu.so
```

So, for example, a valid module library name on CPython 3.10 for macOS is `your_module.cpython-310-darwin.so`, and its equivalent when compiled for PyPy 7.3 on Linux would be `your_module.pypy38-pp73-x86_64-linux-gnu.so`.
Expand Down
1 change: 1 addition & 0 deletions newsfragments/4582.packaging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Drop support for PyPy 3.7 and 3.8.
6 changes: 3 additions & 3 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
PYO3_GUIDE_TARGET = PYO3_TARGET / "guide"
PYO3_DOCS_TARGET = PYO3_TARGET / "doc"
PY_VERSIONS = ("3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13")
PYPY_VERSIONS = ("3.7", "3.8", "3.9", "3.10")
PYPY_VERSIONS = ("3.9", "3.10")


@nox.session(venv_backend="none")
Expand Down Expand Up @@ -646,8 +646,8 @@ def test_version_limits(session: nox.Session):
env["PYO3_USE_ABI3_FORWARD_COMPATIBILITY"] = "1"
_run_cargo(session, "check", env=env)

assert "3.6" not in PYPY_VERSIONS
config_file.set("PyPy", "3.6")
assert "3.8" not in PYPY_VERSIONS
config_file.set("PyPy", "3.8")
_run_cargo(session, "check", env=env, expect_error=True)

assert "3.11" not in PYPY_VERSIONS
Expand Down
56 changes: 28 additions & 28 deletions pyo3-build-config/src/impl_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1648,16 +1648,11 @@ fn default_lib_name_unix(
}
}
},
PythonImplementation::PyPy => {
if version >= (PythonVersion { major: 3, minor: 9 }) {
match ld_version {
Some(ld_version) => format!("pypy{}-c", ld_version),
None => format!("pypy{}.{}-c", version.major, version.minor),
}
} else {
format!("pypy{}-c", version.major)
}
}
PythonImplementation::PyPy => match ld_version {
Some(ld_version) => format!("pypy{}-c", ld_version),
None => format!("pypy{}.{}-c", version.major, version.minor),
},

PythonImplementation::GraalPy => "python-native".to_string(),
}
}
Expand Down Expand Up @@ -2348,17 +2343,17 @@ mod tests {
use PythonImplementation::*;
assert_eq!(
super::default_lib_name_windows(
PythonVersion { major: 3, minor: 7 },
PythonVersion { major: 3, minor: 9 },
CPython,
false,
false,
false,
),
"python37",
"python39",
);
assert_eq!(
super::default_lib_name_windows(
PythonVersion { major: 3, minor: 7 },
PythonVersion { major: 3, minor: 9 },
CPython,
true,
false,
Expand All @@ -2368,17 +2363,17 @@ mod tests {
);
assert_eq!(
super::default_lib_name_windows(
PythonVersion { major: 3, minor: 7 },
PythonVersion { major: 3, minor: 9 },
CPython,
false,
true,
false,
),
"python3.7",
"python3.9",
);
assert_eq!(
super::default_lib_name_windows(
PythonVersion { major: 3, minor: 7 },
PythonVersion { major: 3, minor: 9 },
CPython,
true,
true,
Expand All @@ -2388,35 +2383,35 @@ mod tests {
);
assert_eq!(
super::default_lib_name_windows(
PythonVersion { major: 3, minor: 7 },
PythonVersion { major: 3, minor: 9 },
PyPy,
true,
false,
false,
),
"python37",
"python39",
);
assert_eq!(
super::default_lib_name_windows(
PythonVersion { major: 3, minor: 7 },
PythonVersion { major: 3, minor: 9 },
CPython,
false,
false,
true,
),
"python37_d",
"python39_d",
);
// abi3 debug builds on windows use version-specific lib
// to workaround /~https://github.com/python/cpython/issues/101614
assert_eq!(
super::default_lib_name_windows(
PythonVersion { major: 3, minor: 7 },
PythonVersion { major: 3, minor: 9 },
CPython,
true,
false,
true,
),
"python37_d",
"python39_d",
);
}

Expand Down Expand Up @@ -2447,13 +2442,12 @@ mod tests {
"python3.7md",
);

// PyPy 3.7 ignores ldversion
// PyPy 3.9 includes ldversion
assert_eq!(
super::default_lib_name_unix(PythonVersion { major: 3, minor: 7 }, PyPy, Some("3.7md")),
"pypy3-c",
super::default_lib_name_unix(PythonVersion { major: 3, minor: 9 }, PyPy, None),
"pypy3.9-c",
);

// PyPy 3.9 includes ldversion
assert_eq!(
super::default_lib_name_unix(PythonVersion { major: 3, minor: 9 }, PyPy, Some("3.9d")),
"pypy3.9d-c",
Expand Down Expand Up @@ -2692,7 +2686,7 @@ mod tests {
fn test_build_script_outputs_base() {
let interpreter_config = InterpreterConfig {
implementation: PythonImplementation::CPython,
version: PythonVersion { major: 3, minor: 8 },
version: PythonVersion { major: 3, minor: 9 },
shared: true,
abi3: false,
lib_name: Some("python3".into()),
Expand All @@ -2708,6 +2702,7 @@ mod tests {
[
"cargo:rustc-cfg=Py_3_7".to_owned(),
"cargo:rustc-cfg=Py_3_8".to_owned(),
"cargo:rustc-cfg=Py_3_9".to_owned(),
]
);

Expand All @@ -2720,6 +2715,7 @@ mod tests {
[
"cargo:rustc-cfg=Py_3_7".to_owned(),
"cargo:rustc-cfg=Py_3_8".to_owned(),
"cargo:rustc-cfg=Py_3_9".to_owned(),
"cargo:rustc-cfg=PyPy".to_owned(),
]
);
Expand All @@ -2729,7 +2725,7 @@ mod tests {
fn test_build_script_outputs_abi3() {
let interpreter_config = InterpreterConfig {
implementation: PythonImplementation::CPython,
version: PythonVersion { major: 3, minor: 7 },
version: PythonVersion { major: 3, minor: 9 },
shared: true,
abi3: true,
lib_name: Some("python3".into()),
Expand All @@ -2745,6 +2741,8 @@ mod tests {
interpreter_config.build_script_outputs(),
[
"cargo:rustc-cfg=Py_3_7".to_owned(),
"cargo:rustc-cfg=Py_3_8".to_owned(),
"cargo:rustc-cfg=Py_3_9".to_owned(),
"cargo:rustc-cfg=Py_LIMITED_API".to_owned(),
]
);
Expand All @@ -2757,6 +2755,8 @@ mod tests {
interpreter_config.build_script_outputs(),
[
"cargo:rustc-cfg=Py_3_7".to_owned(),
"cargo:rustc-cfg=Py_3_8".to_owned(),
"cargo:rustc-cfg=Py_3_9".to_owned(),
"cargo:rustc-cfg=PyPy".to_owned(),
"cargo:rustc-cfg=Py_LIMITED_API".to_owned(),
]
Expand Down
2 changes: 1 addition & 1 deletion pyo3-ffi/ACKNOWLEDGEMENTS
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ for binary compatibility, with additional metadata to support PyPy.

For original implementations please see:
- /~https://github.com/python/cpython
- https://foss.heptapod.net/pypy/pypy
- https://github.com/pypy/pypy
9 changes: 6 additions & 3 deletions pyo3-ffi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ Manual][capi] for up-to-date documentation.

# Minimum supported Rust and Python versions

PyO3 supports the following software versions:
- Python 3.7 and up (CPython and PyPy)
- Rust 1.63 and up
Requires Rust 1.63 or greater.

`pyo3-ffi` supports the following Python distributions:
- CPython 3.7 or greater
- PyPy 7.3 (Python 3.9+)
- GraalPy 24.0 or greater (Python 3.10+)

# Example: Building Python Native modules

Expand Down
4 changes: 2 additions & 2 deletions pyo3-ffi/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const SUPPORTED_VERSIONS_CPYTHON: SupportedVersions = SupportedVersions {
};

const SUPPORTED_VERSIONS_PYPY: SupportedVersions = SupportedVersions {
min: PythonVersion { major: 3, minor: 7 },
min: PythonVersion { major: 3, minor: 9 },
max: PythonVersion {
major: 3,
minor: 10,
Expand Down Expand Up @@ -110,7 +110,7 @@ fn ensure_python_version(interpreter_config: &InterpreterConfig) -> Result<()> {
PythonImplementation::CPython => {}
PythonImplementation::PyPy => warn!(
"PyPy does not yet support abi3 so the build artifacts will be version-specific. \
See https://foss.heptapod.net/pypy/pypy/-/issues/3397 for more information."
See https://github.com/pypy/pypy/issues/3397 for more information."
),
PythonImplementation::GraalPy => warn!(
"GraalPy does not support abi3 so the build artifacts will be version-specific."
Expand Down
9 changes: 0 additions & 9 deletions pyo3-ffi/src/cpython/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,15 +210,6 @@ pub type printfunc =
#[repr(C)]
#[derive(Debug)]
pub struct PyTypeObject {
#[cfg(all(PyPy, not(Py_3_9)))]
pub ob_refcnt: Py_ssize_t,
#[cfg(all(PyPy, not(Py_3_9)))]
pub ob_pypy_link: Py_ssize_t,
#[cfg(all(PyPy, not(Py_3_9)))]
pub ob_type: *mut PyTypeObject,
#[cfg(all(PyPy, not(Py_3_9)))]
pub ob_size: Py_ssize_t,
#[cfg(not(all(PyPy, not(Py_3_9))))]
pub ob_base: object::PyVarObject,
#[cfg(GraalPy)]
pub ob_size: Py_ssize_t,
Expand Down
5 changes: 0 additions & 5 deletions pyo3-ffi/src/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@
//! This is the unsafe thin wrapper around the [CPython C API](https://docs.python.org/3/c-api/datetime.html),
//! and covers the various date and time related objects in the Python `datetime`
//! standard library module.
//!
//! A note regarding PyPy (cpyext) support:
//!
//! Support for `PyDateTime_CAPI` is limited as of PyPy 7.0.0.
//! `DateTime_FromTimestamp` and `Date_FromTimestamp` are currently not supported.

#[cfg(GraalPy)]
use crate::{PyLong_AsLong, PyLong_Check, PyObject_GetAttrString, Py_DecRef};
Expand Down
7 changes: 4 additions & 3 deletions pyo3-ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@
//!
//! # Minimum supported Rust and Python versions
//!
//! PyO3 supports the following software versions:
//! - Python 3.7 and up (CPython and PyPy)
//! - Rust 1.63 and up
//! `pyo3-ffi` supports the following Python distributions:
//! - CPython 3.7 or greater
//! - PyPy 7.3 (Python 3.9+)
//! - GraalPy 24.0 or greater (Python 3.10+)
//!
//! # Example: Building Python Native modules
//!
Expand Down
4 changes: 0 additions & 4 deletions pyo3-ffi/src/pystate.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#[cfg(any(not(PyPy), Py_3_9))]
use crate::moduleobject::PyModuleDef;
use crate::object::PyObject;
use std::os::raw::c_int;
Expand Down Expand Up @@ -28,15 +27,12 @@ extern "C" {
#[cfg(not(PyPy))]
pub fn PyInterpreterState_GetID(arg1: *mut PyInterpreterState) -> i64;

#[cfg(any(not(PyPy), Py_3_9))] // only on PyPy since 3.9
#[cfg_attr(PyPy, link_name = "PyPyState_AddModule")]
pub fn PyState_AddModule(arg1: *mut PyObject, arg2: *mut PyModuleDef) -> c_int;

#[cfg(any(not(PyPy), Py_3_9))] // only on PyPy since 3.9
#[cfg_attr(PyPy, link_name = "PyPyState_RemoveModule")]
pub fn PyState_RemoveModule(arg1: *mut PyModuleDef) -> c_int;

#[cfg(any(not(PyPy), Py_3_9))] // only on PyPy since 3.9
// only has PyPy prefix since 3.10
#[cfg_attr(all(PyPy, Py_3_10), link_name = "PyPyState_FindModule")]
pub fn PyState_FindModule(arg1: *mut PyModuleDef) -> *mut PyObject;
Expand Down
Loading
Loading