Merge pull request #3603 from davidhewitt/0.19-deprecations

remove all functionality deprecated in 0.19
This commit is contained in:
David Hewitt 2023-11-28 06:47:30 +00:00 committed by GitHub
commit e62e6cad5d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 11 additions and 189 deletions

View File

@ -1175,7 +1175,7 @@ impl pyo3::impl_::pyclass::PyClassImpl for MyClass {
fn doc(py: Python<'_>) -> pyo3::PyResult<&'static ::std::ffi::CStr> { fn doc(py: Python<'_>) -> pyo3::PyResult<&'static ::std::ffi::CStr> {
use pyo3::impl_::pyclass::*; use pyo3::impl_::pyclass::*;
static DOC: pyo3::once_cell::GILOnceCell<::std::borrow::Cow<'static, ::std::ffi::CStr>> = pyo3::once_cell::GILOnceCell::new(); static DOC: pyo3::sync::GILOnceCell<::std::borrow::Cow<'static, ::std::ffi::CStr>> = pyo3::sync::GILOnceCell::new();
DOC.get_or_try_init(py, || { DOC.get_or_try_init(py, || {
let collector = PyClassImplCollector::<Self>::new(); let collector = PyClassImplCollector::<Self>::new();
build_pyclass_doc(<MyClass as pyo3::PyTypeInfo>::NAME, "", None.or_else(|| collector.new_text_signature())) build_pyclass_doc(<MyClass as pyo3::PyTypeInfo>::NAME, "", None.or_else(|| collector.new_text_signature()))

View File

@ -0,0 +1 @@
Remove all functionality deprecated in PyO3 0.19.

View File

@ -2,14 +2,12 @@ use proc_macro2::{Span, TokenStream};
use quote::{quote_spanned, ToTokens}; use quote::{quote_spanned, ToTokens};
pub enum Deprecation { pub enum Deprecation {
PyClassTextSignature,
PyMethodsNewDeprecatedForm, PyMethodsNewDeprecatedForm,
} }
impl Deprecation { impl Deprecation {
fn ident(&self, span: Span) -> syn::Ident { fn ident(&self, span: Span) -> syn::Ident {
let string = match self { let string = match self {
Deprecation::PyClassTextSignature => "PYCLASS_TEXT_SIGNATURE",
Deprecation::PyMethodsNewDeprecatedForm => "PYMETHODS_NEW_DEPRECATED_FORM", Deprecation::PyMethodsNewDeprecatedForm => "PYMETHODS_NEW_DEPRECATED_FORM",
}; };
syn::Ident::new(string, span) syn::Ident::new(string, span)

View File

@ -6,7 +6,7 @@ use crate::attributes::{
ModuleAttribute, NameAttribute, NameLitStr, RenameAllAttribute, TextSignatureAttribute, ModuleAttribute, NameAttribute, NameLitStr, RenameAllAttribute, TextSignatureAttribute,
TextSignatureAttributeValue, TextSignatureAttributeValue,
}; };
use crate::deprecations::{Deprecation, Deprecations}; use crate::deprecations::Deprecations;
use crate::konst::{ConstAttributes, ConstSpec}; use crate::konst::{ConstAttributes, ConstSpec};
use crate::method::FnSpec; use crate::method::FnSpec;
use crate::pyimpl::{gen_py_const, PyClassMethodsType}; use crate::pyimpl::{gen_py_const, PyClassMethodsType};
@ -34,7 +34,6 @@ pub enum PyClassKind {
pub struct PyClassArgs { pub struct PyClassArgs {
pub class_kind: PyClassKind, pub class_kind: PyClassKind,
pub options: PyClassPyO3Options, pub options: PyClassPyO3Options,
pub deprecations: Deprecations,
} }
impl PyClassArgs { impl PyClassArgs {
@ -42,7 +41,6 @@ impl PyClassArgs {
Ok(PyClassArgs { Ok(PyClassArgs {
class_kind: kind, class_kind: kind,
options: PyClassPyO3Options::parse(input)?, options: PyClassPyO3Options::parse(input)?,
deprecations: Deprecations::new(),
}) })
} }
@ -73,8 +71,6 @@ pub struct PyClassPyO3Options {
pub text_signature: Option<TextSignatureAttribute>, pub text_signature: Option<TextSignatureAttribute>,
pub unsendable: Option<kw::unsendable>, pub unsendable: Option<kw::unsendable>,
pub weakref: Option<kw::weakref>, pub weakref: Option<kw::weakref>,
pub deprecations: Deprecations,
} }
enum PyClassPyO3Option { enum PyClassPyO3Option {
@ -91,7 +87,6 @@ enum PyClassPyO3Option {
Sequence(kw::sequence), Sequence(kw::sequence),
SetAll(kw::set_all), SetAll(kw::set_all),
Subclass(kw::subclass), Subclass(kw::subclass),
TextSignature(TextSignatureAttribute),
Unsendable(kw::unsendable), Unsendable(kw::unsendable),
Weakref(kw::weakref), Weakref(kw::weakref),
} }
@ -125,8 +120,6 @@ impl Parse for PyClassPyO3Option {
input.parse().map(PyClassPyO3Option::SetAll) input.parse().map(PyClassPyO3Option::SetAll)
} else if lookahead.peek(attributes::kw::subclass) { } else if lookahead.peek(attributes::kw::subclass) {
input.parse().map(PyClassPyO3Option::Subclass) input.parse().map(PyClassPyO3Option::Subclass)
} else if lookahead.peek(attributes::kw::text_signature) {
input.parse().map(PyClassPyO3Option::TextSignature)
} else if lookahead.peek(attributes::kw::unsendable) { } else if lookahead.peek(attributes::kw::unsendable) {
input.parse().map(PyClassPyO3Option::Unsendable) input.parse().map(PyClassPyO3Option::Unsendable)
} else if lookahead.peek(attributes::kw::weakref) { } else if lookahead.peek(attributes::kw::weakref) {
@ -181,11 +174,6 @@ impl PyClassPyO3Options {
PyClassPyO3Option::Sequence(sequence) => set_option!(sequence), PyClassPyO3Option::Sequence(sequence) => set_option!(sequence),
PyClassPyO3Option::SetAll(set_all) => set_option!(set_all), PyClassPyO3Option::SetAll(set_all) => set_option!(set_all),
PyClassPyO3Option::Subclass(subclass) => set_option!(subclass), PyClassPyO3Option::Subclass(subclass) => set_option!(subclass),
PyClassPyO3Option::TextSignature(text_signature) => {
self.deprecations
.push(Deprecation::PyClassTextSignature, text_signature.span());
set_option!(text_signature)
}
PyClassPyO3Option::Unsendable(unsendable) => set_option!(unsendable), PyClassPyO3Option::Unsendable(unsendable) => set_option!(unsendable),
PyClassPyO3Option::Weakref(weakref) => set_option!(weakref), PyClassPyO3Option::Weakref(weakref) => set_option!(weakref),
} }
@ -355,7 +343,7 @@ fn impl_class(
methods_type: PyClassMethodsType, methods_type: PyClassMethodsType,
krate: syn::Path, krate: syn::Path,
) -> syn::Result<TokenStream> { ) -> syn::Result<TokenStream> {
let pytypeinfo_impl = impl_pytypeinfo(cls, args, Some(&args.options.deprecations)); let pytypeinfo_impl = impl_pytypeinfo(cls, args, None);
let py_class_impl = PyClassImplsBuilder::new( let py_class_impl = PyClassImplsBuilder::new(
cls, cls,
@ -989,8 +977,6 @@ impl<'a> PyClassImplsBuilder<'a> {
let default_slot_defs = self.default_slots.iter().map(|slot| &slot.slot_def); let default_slot_defs = self.default_slots.iter().map(|slot| &slot.slot_def);
let freelist_slots = self.freelist_slots(); let freelist_slots = self.freelist_slots();
let deprecations = &self.attr.deprecations;
let class_mutability = if self.attr.options.frozen.is_some() { let class_mutability = if self.attr.options.frozen.is_some() {
quote! { quote! {
ImmutableChild ImmutableChild
@ -1040,7 +1026,6 @@ impl<'a> PyClassImplsBuilder<'a> {
fn items_iter() -> _pyo3::impl_::pyclass::PyClassItemsIter { fn items_iter() -> _pyo3::impl_::pyclass::PyClassItemsIter {
use _pyo3::impl_::pyclass::*; use _pyo3::impl_::pyclass::*;
let collector = PyClassImplCollector::<Self>::new(); let collector = PyClassImplCollector::<Self>::new();
#deprecations;
static INTRINSIC_ITEMS: PyClassItems = PyClassItems { static INTRINSIC_ITEMS: PyClassItems = PyClassItems {
methods: &[#(#default_method_defs),*], methods: &[#(#default_method_defs),*],
slots: &[#(#default_slot_defs),* #(#freelist_slots),*], slots: &[#(#default_slot_defs),* #(#freelist_slots),*],
@ -1050,7 +1035,7 @@ impl<'a> PyClassImplsBuilder<'a> {
fn doc(py: _pyo3::Python<'_>) -> _pyo3::PyResult<&'static ::std::ffi::CStr> { fn doc(py: _pyo3::Python<'_>) -> _pyo3::PyResult<&'static ::std::ffi::CStr> {
use _pyo3::impl_::pyclass::*; use _pyo3::impl_::pyclass::*;
static DOC: _pyo3::once_cell::GILOnceCell<::std::borrow::Cow<'static, ::std::ffi::CStr>> = _pyo3::once_cell::GILOnceCell::new(); static DOC: _pyo3::sync::GILOnceCell<::std::borrow::Cow<'static, ::std::ffi::CStr>> = _pyo3::sync::GILOnceCell::new();
DOC.get_or_try_init(py, || { DOC.get_or_try_init(py, || {
let collector = PyClassImplCollector::<Self>::new(); let collector = PyClassImplCollector::<Self>::new();
build_pyclass_doc(<#cls as _pyo3::PyTypeInfo>::NAME, #doc, #deprecated_text_signature.or_else(|| collector.new_text_signature())) build_pyclass_doc(<#cls as _pyo3::PyTypeInfo>::NAME, #doc, #deprecated_text_signature.or_else(|| collector.new_text_signature()))

View File

@ -50,7 +50,7 @@
//! ``` //! ```
use crate::exceptions::PyValueError; use crate::exceptions::PyValueError;
use crate::once_cell::GILOnceCell; use crate::sync::GILOnceCell;
use crate::types::PyType; use crate::types::PyType;
use crate::{intern, FromPyObject, IntoPy, Py, PyAny, PyObject, PyResult, Python, ToPyObject}; use crate::{intern, FromPyObject, IntoPy, Py, PyAny, PyObject, PyResult, Python, ToPyObject};
use rust_decimal::Decimal; use rust_decimal::Decimal;

View File

@ -10,8 +10,6 @@ where
{ {
fn into_py(self, py: Python<'_>) -> PyObject { fn into_py(self, py: Python<'_>) -> PyObject {
unsafe { unsafe {
#[allow(deprecated)] // we're not on edition 2021 yet
let elements = std::array::IntoIter::new(self);
let len = N as ffi::Py_ssize_t; let len = N as ffi::Py_ssize_t;
let ptr = ffi::PyList_New(len); let ptr = ffi::PyList_New(len);
@ -21,7 +19,7 @@ where
// - its Drop cleans up the list if user code panics. // - its Drop cleans up the list if user code panics.
let list: Py<PyAny> = Py::from_owned_ptr(py, ptr); let list: Py<PyAny> = Py::from_owned_ptr(py, ptr);
for (i, obj) in (0..len).zip(elements) { for (i, obj) in (0..len).zip(self) {
let obj = obj.into_py(py).into_ptr(); let obj = obj.into_py(py).into_ptr();
#[cfg(not(Py_LIMITED_API))] #[cfg(not(Py_LIMITED_API))]

View File

@ -1,10 +1,4 @@
//! Symbols used to denote deprecated usages of PyO3's proc macros. //! Symbols used to denote deprecated usages of PyO3's proc macros.
#[deprecated(
since = "0.19.0",
note = "put `text_signature` on `#[new]` instead of `#[pyclass]`"
)]
pub const PYCLASS_TEXT_SIGNATURE: () = ();
#[deprecated(since = "0.20.0", note = "use `#[new]` instead of `#[__new__]`")] #[deprecated(since = "0.20.0", note = "use `#[new]` instead of `#[__new__]`")]
pub const PYMETHODS_NEW_DEPRECATED_FORM: () = (); pub const PYMETHODS_NEW_DEPRECATED_FORM: () = ();

View File

@ -427,15 +427,6 @@ pub mod type_object;
pub mod types; pub mod types;
mod version; mod version;
#[doc(hidden)]
#[deprecated(since = "0.19.0", note = "Please use the `sync` module instead.")]
pub mod once_cell {
// FIXME: We want to deprecate these,
// but that does not yet work for re-exports,
// c.f. https://github.com/rust-lang/rust/issues/30827
pub use crate::sync::{GILOnceCell, Interned};
}
#[allow(unused_imports)] // with no features enabled this module has no public exports #[allow(unused_imports)] // with no features enabled this module has no public exports
pub use crate::conversions::*; pub use crate::conversions::*;

View File

@ -232,13 +232,6 @@ impl PySequence {
} }
} }
/// Returns a fresh list based on the Sequence.
#[inline]
#[deprecated(since = "0.19.0", note = "renamed to .to_list()")]
pub fn list(&self) -> PyResult<&PyList> {
self.to_list()
}
/// Returns a fresh tuple based on the Sequence. /// Returns a fresh tuple based on the Sequence.
#[inline] #[inline]
pub fn to_tuple(&self) -> PyResult<&PyTuple> { pub fn to_tuple(&self) -> PyResult<&PyTuple> {
@ -248,13 +241,6 @@ impl PySequence {
} }
} }
/// Returns a fresh tuple based on the Sequence.
#[inline]
#[deprecated(since = "0.19.0", note = "renamed to .to_tuple()")]
pub fn tuple(&self) -> PyResult<&PyTuple> {
self.to_tuple()
}
/// Register a pyclass as a subclass of `collections.abc.Sequence` (from the Python standard /// Register a pyclass as a subclass of `collections.abc.Sequence` (from the Python standard
/// library). This is equvalent to `collections.abc.Sequence.register(T)` in Python. /// library). This is equvalent to `collections.abc.Sequence.register(T)` in Python.
/// This registration is required for a pyclass to be downcastable from `PyAny` to `PySequence`. /// This registration is required for a pyclass to be downcastable from `PyAny` to `PySequence`.
@ -803,10 +789,6 @@ mod tests {
let ob = v.to_object(py); let ob = v.to_object(py);
let seq = ob.downcast::<PySequence>(py).unwrap(); let seq = ob.downcast::<PySequence>(py).unwrap();
assert!(seq.to_list().unwrap().eq(PyList::new(py, &v)).unwrap()); assert!(seq.to_list().unwrap().eq(PyList::new(py, &v)).unwrap());
#[allow(deprecated)]
{
assert!(seq.list().is_ok());
}
}); });
} }
@ -821,10 +803,6 @@ mod tests {
.unwrap() .unwrap()
.eq(PyList::new(py, ["f", "o", "o"])) .eq(PyList::new(py, ["f", "o", "o"]))
.unwrap()); .unwrap());
#[allow(deprecated)]
{
assert!(seq.list().is_ok());
}
}); });
} }
@ -839,10 +817,6 @@ mod tests {
.unwrap() .unwrap()
.eq(PyTuple::new(py, ["foo", "bar"])) .eq(PyTuple::new(py, ["foo", "bar"]))
.unwrap()); .unwrap());
#[allow(deprecated)]
{
assert!(seq.tuple().is_ok());
}
}); });
} }
@ -853,10 +827,6 @@ mod tests {
let ob = v.to_object(py); let ob = v.to_object(py);
let seq = ob.downcast::<PySequence>(py).unwrap(); let seq = ob.downcast::<PySequence>(py).unwrap();
assert!(seq.to_tuple().unwrap().eq(PyTuple::new(py, &v)).unwrap()); assert!(seq.to_tuple().unwrap().eq(PyTuple::new(py, &v)).unwrap());
#[allow(deprecated)]
{
assert!(seq.tuple().is_ok());
}
}); });
} }

View File

@ -435,111 +435,3 @@ fn test_raw_identifiers() {
); );
}); });
} }
#[allow(deprecated)]
mod deprecated {
use crate::py_assert;
use pyo3::prelude::*;
#[test]
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_10)), ignore)]
fn class_with_docs_and_signature() {
/// docs line1
#[pyclass]
/// docs line2
#[pyo3(text_signature = "(a, b=None, *, c=42)")]
/// docs line3
struct MyClass {}
#[pymethods]
impl MyClass {
#[new]
#[pyo3(signature = (a, b=None, *, c=42))]
fn __new__(a: i32, b: Option<i32>, c: i32) -> Self {
let _ = (a, b, c);
Self {}
}
}
Python::with_gil(|py| {
let typeobj = py.get_type::<MyClass>();
py_assert!(
py,
typeobj,
"typeobj.__doc__ == 'docs line1\\ndocs line2\\ndocs line3'"
);
py_assert!(
py,
typeobj,
"typeobj.__text_signature__ == '(a, b=None, *, c=42)'"
);
});
}
#[test]
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_10)), ignore)]
fn class_with_deprecated_text_signature() {
#[pyclass]
#[pyo3(text_signature = "(a, b=None, *, c=42)")]
struct MyClass {}
#[pymethods]
impl MyClass {
#[new]
#[pyo3(signature = (a, b=None, *, c=42))]
fn __new__(a: i32, b: Option<i32>, c: i32) -> Self {
let _ = (a, b, c);
Self {}
}
}
Python::with_gil(|py| {
let typeobj = py.get_type::<MyClass>();
py_assert!(
py,
typeobj,
"typeobj.__doc__ is None or typeobj.__doc__ == ''"
);
py_assert!(
py,
typeobj,
"typeobj.__text_signature__ == '(a, b=None, *, c=42)'"
);
});
}
#[test]
#[cfg_attr(all(Py_LIMITED_API, not(Py_3_10)), ignore)]
fn class_with_deprecated_text_signature_and_on_new() {
#[pyclass(text_signature = "(a, b=None, *, c=42)")]
struct MyClass {}
#[pymethods]
impl MyClass {
#[new]
#[pyo3(signature = (a, b=None, *, c=42), text_signature = "(NOT, THIS, ONE)")]
fn __new__(a: i32, b: Option<i32>, c: i32) -> Self {
let _ = (a, b, c);
Self {}
}
}
Python::with_gil(|py| {
let typeobj = py.get_type::<MyClass>();
py_assert!(
py,
typeobj,
"typeobj.__doc__ is None or typeobj.__doc__ == ''"
);
// Deprecated `#[pyclass(text_signature)]` attribute will be preferred
// for backwards-compatibility.
py_assert!(
py,
typeobj,
"typeobj.__text_signature__ == '(a, b=None, *, c=42)'"
);
});
}
}

View File

@ -3,7 +3,6 @@
use pyo3::prelude::*; use pyo3::prelude::*;
#[pyclass] #[pyclass]
#[pyo3(text_signature = "()")]
struct MyClass; struct MyClass;
#[pymethods] #[pymethods]

View File

@ -1,7 +1,7 @@
error: use of deprecated constant `pyo3::impl_::deprecations::PYMETHODS_NEW_DEPRECATED_FORM`: use `#[new]` instead of `#[__new__]` error: use of deprecated constant `pyo3::impl_::deprecations::PYMETHODS_NEW_DEPRECATED_FORM`: use `#[new]` instead of `#[__new__]`
--> tests/ui/deprecations.rs:11:7 --> tests/ui/deprecations.rs:10:7
| |
11 | #[__new__] 10 | #[__new__]
| ^^^^^^^ | ^^^^^^^
| |
note: the lint level is defined here note: the lint level is defined here
@ -9,9 +9,3 @@ note: the lint level is defined here
| |
1 | #![deny(deprecated)] 1 | #![deny(deprecated)]
| ^^^^^^^^^^ | ^^^^^^^^^^
error: use of deprecated constant `pyo3::impl_::deprecations::PYCLASS_TEXT_SIGNATURE`: put `text_signature` on `#[new]` instead of `#[pyclass]`
--> tests/ui/deprecations.rs:6:8
|
6 | #[pyo3(text_signature = "()")]
| ^^^^^^^^^^^^^^

View File

@ -1,4 +1,4 @@
error: expected one of: `crate`, `dict`, `extends`, `freelist`, `frozen`, `get_all`, `mapping`, `module`, `name`, `rename_all`, `sequence`, `set_all`, `subclass`, `text_signature`, `unsendable`, `weakref` error: expected one of: `crate`, `dict`, `extends`, `freelist`, `frozen`, `get_all`, `mapping`, `module`, `name`, `rename_all`, `sequence`, `set_all`, `subclass`, `unsendable`, `weakref`
--> tests/ui/invalid_pyclass_args.rs:3:11 --> tests/ui/invalid_pyclass_args.rs:3:11
| |
3 | #[pyclass(extend=pyo3::types::PyDict)] 3 | #[pyclass(extend=pyo3::types::PyDict)]
@ -46,7 +46,7 @@ error: expected string literal
24 | #[pyclass(module = my_module)] 24 | #[pyclass(module = my_module)]
| ^^^^^^^^^ | ^^^^^^^^^
error: expected one of: `crate`, `dict`, `extends`, `freelist`, `frozen`, `get_all`, `mapping`, `module`, `name`, `rename_all`, `sequence`, `set_all`, `subclass`, `text_signature`, `unsendable`, `weakref` error: expected one of: `crate`, `dict`, `extends`, `freelist`, `frozen`, `get_all`, `mapping`, `module`, `name`, `rename_all`, `sequence`, `set_all`, `subclass`, `unsendable`, `weakref`
--> tests/ui/invalid_pyclass_args.rs:27:11 --> tests/ui/invalid_pyclass_args.rs:27:11
| |
27 | #[pyclass(weakrev)] 27 | #[pyclass(weakrev)]