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

Complete abi3 support #1152

Merged
merged 65 commits into from
Oct 27, 2020
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
4004620
Proof of concept of using PEP384s PyType_Spec
alex Sep 1, 2020
62a175e
Merge pull request #1132 from alex/abi3-class-creation
kngwyu Sep 5, 2020
d2a10b6
Introduce all-apis feature to support abi3
kngwyu Sep 5, 2020
c2f10e2
Restructure protcol-table initialization
kngwyu Sep 5, 2020
1941f4d
Rename all-apis with unstable-api
kngwyu Sep 6, 2020
e0f75f8
Fix missing PyGetSetDef_INIT and Adress clippy warnings
kngwyu Sep 6, 2020
4cd6d4c
Fixed a few compilation errors on the abi3 branch
alex Sep 6, 2020
3b61df2
Merge pull request #1161 from alex/abi3-fix-errors
kngwyu Sep 7, 2020
80e2497
Complete the process of disabling buffers with Py_LIMITED_API
alex Sep 7, 2020
71a7b1a
Properly mark a funtion as limited API only
alex Sep 7, 2020
4325a59
Merge pull request #1164 from alex/abi3-no-free-func
kngwyu Sep 8, 2020
e8936be
Merge pull request #1162 from alex/disable-buffer-more
kngwyu Sep 8, 2020
0709a02
Fill tp_dict on types in an abi3-friendly way
alex Sep 8, 2020
679326e
Merge pull request #1165 from alex/abi3-fill-dict
kngwyu Sep 8, 2020
117f60b
Make PyType::name abi3 compatible
alex Sep 8, 2020
a009c23
Merge pull request #1166 from alex/abi3-name
kngwyu Sep 9, 2020
d6c9435
Implement set iterators in terms of limited API
alex Sep 8, 2020
0bc2393
Merge pull request #1167 from alex/abi3-sets
davidhewitt Sep 9, 2020
7a4c5e2
Merge branch 'master' into abi3
kngwyu Sep 9, 2020
5bfb467
Merge branch 'master' into abi3-merge-master
alex Sep 10, 2020
4d5c208
fixes
alex Sep 10, 2020
3cb0b11
Update src/err/mod.rs
alex Sep 12, 2020
afc2d10
Merge pull request #1172 from alex/abi3-merge-master
kngwyu Sep 13, 2020
d0c2ebf
Remove finalizer code that was never reachable and switch field access
alex Sep 13, 2020
1b2d267
Make unicode handling abi3 friendly
alex Sep 15, 2020
517af8c
Merge pull request #1183 from alex/abi3-tp-finalizer
kngwyu Sep 15, 2020
2ec1c3b
Merge pull request #1187 from alex/abi3-to-str
kngwyu Sep 15, 2020
870914d
Make check warning clean in limited API mode
alex Sep 15, 2020
a2dc4c1
Merge pull request #1188 from alex/abi3-warnings
kngwyu Sep 16, 2020
ba10560
Get all the tests building, everythign except doctests passes!
alex Sep 15, 2020
c87a59c
Merge pull request #1189 from alex/abi3-tests-compile
kngwyu Sep 18, 2020
c07e1aa
Use abi3 feature, instead of unstable-api
kngwyu Sep 19, 2020
2a85c17
Run abi3 tests in CI
alex Sep 19, 2020
7644d67
Inhibit subclassing native types with ABI3 set
kngwyu Sep 19, 2020
9d85591
Hack __text_signature__ back to working with abi3
alex Sep 19, 2020
4862f56
Merge pull request #1202 from alex/patch-1
kngwyu Sep 19, 2020
869a5e2
Fix an abi3 ui test for the latest Rustc
kngwyu Sep 20, 2020
1985578
Don't compile extends=PyDict test in class.md with abi3
kngwyu Sep 20, 2020
e33e58f
Merge pull request #1201 from alex/abi3-text-signature
kngwyu Sep 20, 2020
d8c8c17
Link python3.lib instead of python3x.lib on Windows in abi3 mode
alex Sep 23, 2020
e615ce8
Start documenting abi3 support
alex Sep 20, 2020
c22dd6c
Remove symbols not available in abi3
alex Sep 23, 2020
0fde737
Merge pull request #1207 from alex/abi3-link-python3
kngwyu Sep 28, 2020
20a93ed
Merge pull request #1203 from alex/abi3-docs
davidhewitt Oct 9, 2020
140790b
Merge branch 'master' into abi3-merge-master
alex Oct 10, 2020
398369f
Fixed warning
alex Oct 10, 2020
d42dbda
Merge pull request #1220 from alex/abi3-merge-master
kngwyu Oct 10, 2020
877667a
Improved documentation
alex Oct 11, 2020
137196d
Merge pull request #1227 from alex/abi3-improvements
davidhewitt Oct 11, 2020
aabad7c
Assorted updates to the abi3 branch from review
alex Oct 11, 2020
0665c02
Merge pull request #1230 from alex/abi3-final
davidhewitt Oct 12, 2020
9e34835
Merge branch 'master' into abi3-merge-master
alex Oct 12, 2020
5060379
Fix changelog
alex Oct 12, 2020
2923b4d
Fix for MSRV
alex Oct 12, 2020
4298435
Merge pull request #1237 from alex/abi3-merge-master
davidhewitt Oct 12, 2020
ba6f0ec
Merge branch 'master' into abi3-merge-master
alex Oct 18, 2020
265db33
Fixes for PyIterator
alex Oct 18, 2020
781bb9f
Merge branch 'master' into abi3-merge-master
alex Oct 18, 2020
90a825d
Merge branch 'master' into abi3-merge-master
alex Oct 19, 2020
f74b649
Merge pull request #1245 from alex/abi3-merge-master
davidhewitt Oct 19, 2020
eb8ff15
Renew PyProtoMethods for new ABI3-based type construction
kngwyu Oct 17, 2020
6627658
Renew proc-macros for new `#[pyproto]` backend
kngwyu Oct 19, 2020
16ad3bf
Use TypedSlot as internal representation of ffi::PyType_Slot
kngwyu Oct 26, 2020
95bec25
Merge pull request #1254 from PyO3/abi3-new-proto
kngwyu Oct 27, 2020
eb0e6f6
Note the minimum required version of maturin supporting abi3
kngwyu Oct 27, 2020
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ jobs:
- run: rustup set default-host ${{ matrix.platform.rust-target }}

- name: Build without default features
run: cargo build --no-default-features --verbose
run: cargo build --no-default-features --features "unstable-api" --verbose

- name: Build with default features
run: cargo build --features "num-bigint num-complex" --verbose
Expand Down
11 changes: 5 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,12 @@ trybuild = "1.0.23"
rustversion = "1.0"

[features]
default = ["macros"]
default = ["macros", "unstable-api"]
macros = ["ctor", "indoc", "inventory", "paste", "pyo3cls", "unindent"]
# Enable unstable API incompatible with abi3(PEP384).
# See https://www.python.org/dev/peps/pep-0384/ more.
unstable-api = []

# Optimizes PyObject to Vec conversion and so on.
nightly = []

Expand All @@ -46,11 +50,6 @@ python3 = []
# so that the module can also be used with statically linked python interpreters.
extension-module = []

# The stable cpython abi as defined in PEP 384. Currently broken with
# many compilation errors. Pull Requests working towards fixing that
# are welcome.
# abi3 = []

[workspace]
members = [
"pyo3cls",
Expand Down
2 changes: 1 addition & 1 deletion build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,7 @@ fn configure(interpreter_config: &InterpreterConfig) -> Result<String> {
bail!("Python 2 is not supported");
}

if env::var_os("CARGO_FEATURE_ABI3").is_some() {
if env::var_os("CARGO_FEATURE_UNSTABLE_API").is_none() {
println!("cargo:rustc-cfg=Py_LIMITED_API");
}

Expand Down
4 changes: 3 additions & 1 deletion examples/rustapi_module/tests/test_datetime.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import datetime as pdt
import platform
import struct
import re
import sys

import pytest
Expand Down Expand Up @@ -327,4 +328,5 @@ def test_tz_class_introspection():
tzi = rdt.TzClass()

assert tzi.__class__ == rdt.TzClass
assert repr(tzi).startswith("<TzClass object at")
# PyPy generate <importlib.bootstrap.TzClass ...> for some reason.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we create an issue to investigate this PyPy behaviour in a follow-up? Seems like a potential bug.

Suggested change
# PyPy generate <importlib.bootstrap.TzClass ...> for some reason.
# PyPy generates <importlib.bootstrap.TzClass ...> for some reason.

assert re.match(r"^<[\w\.]*TzClass object at", repr(tzi))
4 changes: 2 additions & 2 deletions guide/src/class.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ or by `self_.into_super()` as `PyRef<Self::BaseClass>`.
```rust
# use pyo3::prelude::*;

#[pyclass]
#[pyclass(subclass)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a breaking change that needs to go in the CHANGELOG, and possibly other guide documentation?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I agree.

struct BaseClass {
val1: usize,
}
Expand All @@ -222,7 +222,7 @@ impl BaseClass {
}
}

#[pyclass(extends=BaseClass)]
#[pyclass(extends=BaseClass, subclass)]
struct SubClass {
val2: usize,
}
Expand Down
10 changes: 5 additions & 5 deletions pyo3-derive-backend/src/defs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ pub const OBJECT: Proto = Proto {

pub const ASYNC: Proto = Proto {
name: "Async",
slot_table: "pyo3::ffi::PyAsyncMethods",
slot_table: "pyo3::class::pyasync::PyAsyncMethods",
set_slot_table: "set_async_methods",
methods: &[
MethodProto::UnaryS {
Expand Down Expand Up @@ -220,7 +220,7 @@ pub const ASYNC: Proto = Proto {

pub const BUFFER: Proto = Proto {
name: "Buffer",
slot_table: "pyo3::ffi::PyBufferProcs",
slot_table: "pyo3::class::buffer::PyBufferProcs",
set_slot_table: "set_buffer_methods",
methods: &[
MethodProto::Unary {
Expand Down Expand Up @@ -358,7 +358,7 @@ pub const ITER: Proto = Proto {

pub const MAPPING: Proto = Proto {
name: "Mapping",
slot_table: "pyo3::ffi::PyMappingMethods",
slot_table: "pyo3::class::mapping::PyMappingMethods",
set_slot_table: "set_mapping_methods",
methods: &[
MethodProto::Unary {
Expand Down Expand Up @@ -401,7 +401,7 @@ pub const MAPPING: Proto = Proto {

pub const SEQ: Proto = Proto {
name: "Sequence",
slot_table: "pyo3::ffi::PySequenceMethods",
slot_table: "pyo3::class::sequence::PySequenceMethods",
set_slot_table: "set_sequence_methods",
methods: &[
MethodProto::Unary {
Expand Down Expand Up @@ -467,7 +467,7 @@ pub const SEQ: Proto = Proto {

pub const NUM: Proto = Proto {
name: "Number",
slot_table: "pyo3::ffi::PyNumberMethods",
slot_table: "pyo3::class::number::PyNumberMethods",
set_slot_table: "set_number_methods",
methods: &[
MethodProto::BinaryS {
Expand Down
18 changes: 10 additions & 8 deletions src/class/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,6 @@ pub struct PyObjectMethods {

#[doc(hidden)]
impl PyObjectMethods {
pub(crate) fn update_typeobj(&self, type_object: &mut ffi::PyTypeObject) {
type_object.tp_str = self.tp_str;
type_object.tp_repr = self.tp_repr;
type_object.tp_hash = self.tp_hash;
type_object.tp_getattro = self.tp_getattro;
type_object.tp_richcompare = self.tp_richcompare;
type_object.tp_setattro = self.tp_setattro;
}
// Set functions used by `#[pyproto]`.
pub fn set_str<T>(&mut self)
where
Expand Down Expand Up @@ -216,6 +208,16 @@ impl PyObjectMethods {
{
self.nb_bool = py_unary_func!(PyObjectBoolProtocol, T::__bool__, c_int);
}

pub(crate) fn update_slots(&self, slots: &mut crate::pyclass::TypeSlots) {
slots.maybe_push(ffi::Py_tp_str, self.tp_str.map(|v| v as _));
slots.maybe_push(ffi::Py_tp_repr, self.tp_repr.map(|v| v as _));
slots.maybe_push(ffi::Py_tp_hash, self.tp_hash.map(|v| v as _));
slots.maybe_push(ffi::Py_tp_getattro, self.tp_getattro.map(|v| v as _));
slots.maybe_push(ffi::Py_tp_richcompare, self.tp_richcompare.map(|v| v as _));
slots.maybe_push(ffi::Py_tp_setattro, self.tp_setattro.map(|v| v as _));
slots.maybe_push(ffi::Py_nb_bool, self.nb_bool.map(|v| v as _));
}
}

fn tp_getattro<T>() -> Option<ffi::binaryfunc>
Expand Down
15 changes: 11 additions & 4 deletions src/class/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,19 @@
//! For more information check [buffer protocol](https://docs.python.org/3/c-api/buffer.html)
//! c-api
use crate::callback::IntoPyCallbackOutput;
use crate::{
ffi::{self, PyBufferProcs},
PyCell, PyClass, PyRefMut,
};
use crate::{ffi, PyCell, PyClass, PyRefMut};
use std::os::raw::c_int;

#[cfg(Py_LIMITED_API)]
#[derive(Clone, Default)]
pub struct PyBufferProcs {
pub bf_getbuffer: Option<ffi::getbufferproc>,
pub bf_releasebuffer: Option<ffi::releasebufferproc>,
}

#[cfg(not(Py_LIMITED_API))]
pub use ffi::PyBufferProcs;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we need any of the changes in this file... in class/mod.rs I think we skip this whole file if using the limited API? (And it doesn't look like we change that in this PR.)

/// Buffer protocol interface
///
/// For more information check [buffer protocol](https://docs.python.org/3/c-api/buffer.html)
Expand Down
8 changes: 4 additions & 4 deletions src/class/descr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,6 @@ pub struct PyDescrMethods {

#[doc(hidden)]
impl PyDescrMethods {
pub(crate) fn update_typeobj(&self, type_object: &mut ffi::PyTypeObject) {
type_object.tp_descr_get = self.tp_descr_get;
type_object.tp_descr_set = self.tp_descr_set;
}
pub fn set_descr_get<T>(&mut self)
where
T: for<'p> PyDescrGetProtocol<'p>,
Expand All @@ -95,4 +91,8 @@ impl PyDescrMethods {
{
self.tp_descr_set = py_ternarys_func!(PyDescrSetProtocol, T::__set__, c_int);
}
pub(crate) fn update_slots(&self, slots: &mut crate::pyclass::TypeSlots) {
slots.maybe_push(ffi::Py_tp_descr_get, self.tp_descr_get.map(|v| v as _));
slots.maybe_push(ffi::Py_tp_descr_set, self.tp_descr_set.map(|v| v as _));
}
}
8 changes: 4 additions & 4 deletions src/class/gc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ pub struct PyGCMethods {

#[doc(hidden)]
impl PyGCMethods {
pub(crate) fn update_typeobj(&self, type_object: &mut ffi::PyTypeObject) {
type_object.tp_traverse = self.tp_traverse;
type_object.tp_clear = self.tp_clear;
pub(crate) fn update_slots(&self, slots: &mut crate::pyclass::TypeSlots) {
slots.maybe_push(ffi::Py_tp_traverse, self.tp_traverse.map(|v| v as _));
slots.maybe_push(ffi::Py_tp_clear, self.tp_clear.map(|v| v as _));
}

pub fn set_traverse<T>(&mut self)
Expand All @@ -48,7 +48,7 @@ impl PyGCMethods {
}

/// Object visitor for GC.
#[derive(Copy, Clone)]
davidhewitt marked this conversation as resolved.
Show resolved Hide resolved
#[derive(Clone)]
pub struct PyVisit<'p> {
visit: ffi::visitproc,
arg: *mut c_void,
Expand Down
8 changes: 4 additions & 4 deletions src/class/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,6 @@ pub struct PyIterMethods {

#[doc(hidden)]
impl PyIterMethods {
pub(crate) fn update_typeobj(&self, type_object: &mut ffi::PyTypeObject) {
type_object.tp_iter = self.tp_iter;
type_object.tp_iternext = self.tp_iternext;
}
pub fn set_iter<T>(&mut self)
where
T: for<'p> PyIterIterProtocol<'p>,
Expand All @@ -95,6 +91,10 @@ impl PyIterMethods {
{
self.tp_iternext = py_unarys_func!(PyIterNextProtocol, T::__next__);
}
pub(crate) fn update_slots(&self, slots: &mut crate::pyclass::TypeSlots) {
slots.maybe_push(ffi::Py_tp_iter, self.tp_iter.map(|v| v as _));
slots.maybe_push(ffi::Py_tp_iternext, self.tp_iternext.map(|v| v as _));
}
}

/// Output of `__next__` which can either `yield` the next value in the iteration, or
Expand Down
21 changes: 20 additions & 1 deletion src/class/mapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ use crate::callback::IntoPyCallbackOutput;
use crate::err::PyErr;
use crate::{exceptions, ffi, FromPyObject, PyClass, PyObject};

#[cfg(Py_LIMITED_API)]
#[derive(Clone, Default)]
pub struct PyMappingMethods {
pub mp_length: Option<ffi::lenfunc>,
pub mp_subscript: Option<ffi::binaryfunc>,
pub mp_ass_subscript: Option<ffi::objobjargproc>,
}

#[cfg(not(Py_LIMITED_API))]
pub use ffi::PyMappingMethods;

/// Mapping interface
#[allow(unused_variables)]
pub trait PyMappingProtocol<'p>: PyClass {
Expand Down Expand Up @@ -74,7 +85,7 @@ pub trait PyMappingReversedProtocol<'p>: PyMappingProtocol<'p> {
}

#[doc(hidden)]
impl ffi::PyMappingMethods {
impl PyMappingMethods {
pub fn set_length<T>(&mut self)
where
T: for<'p> PyMappingLenProtocol<'p>,
Expand Down Expand Up @@ -111,4 +122,12 @@ impl ffi::PyMappingMethods {
__delitem__
);
}
pub(crate) fn update_slots(&self, slots: &mut crate::pyclass::TypeSlots) {
slots.maybe_push(ffi::Py_mp_length, self.mp_length.map(|v| v as _));
slots.maybe_push(ffi::Py_mp_subscript, self.mp_subscript.map(|v| v as _));
slots.maybe_push(
ffi::Py_mp_ass_subscript,
self.mp_ass_subscript.map(|v| v as _),
);
}
}
Loading