From 5c6d49084f6a08725e90bcdf9ace282f5cd7fb0a Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Mon, 27 Nov 2023 22:02:19 +0000 Subject: [PATCH] remove all functionality deprecated in 0.19 --- guide/src/class.md | 2 +- newsfragments/3603.removed.md | 1 + pyo3-macros-backend/src/deprecations.rs | 2 - pyo3-macros-backend/src/pyclass.rs | 21 +---- src/conversions/rust_decimal.rs | 2 +- src/conversions/std/array.rs | 4 +- src/impl_/deprecations.rs | 6 -- src/lib.rs | 9 -- src/types/sequence.rs | 30 ------- tests/test_text_signature.rs | 108 ------------------------ tests/ui/deprecations.rs | 1 - tests/ui/deprecations.stderr | 10 +-- tests/ui/invalid_pyclass_args.stderr | 4 +- 13 files changed, 11 insertions(+), 189 deletions(-) create mode 100644 newsfragments/3603.removed.md diff --git a/guide/src/class.md b/guide/src/class.md index dbcbc444..ed71cb2e 100644 --- a/guide/src/class.md +++ b/guide/src/class.md @@ -1175,7 +1175,7 @@ impl pyo3::impl_::pyclass::PyClassImpl for MyClass { fn doc(py: Python<'_>) -> pyo3::PyResult<&'static ::std::ffi::CStr> { 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, || { let collector = PyClassImplCollector::::new(); build_pyclass_doc(::NAME, "", None.or_else(|| collector.new_text_signature())) diff --git a/newsfragments/3603.removed.md b/newsfragments/3603.removed.md new file mode 100644 index 00000000..e8f5004e --- /dev/null +++ b/newsfragments/3603.removed.md @@ -0,0 +1 @@ +Remove all functionality deprecated in PyO3 0.19. diff --git a/pyo3-macros-backend/src/deprecations.rs b/pyo3-macros-backend/src/deprecations.rs index 0bfefd61..ea292273 100644 --- a/pyo3-macros-backend/src/deprecations.rs +++ b/pyo3-macros-backend/src/deprecations.rs @@ -2,14 +2,12 @@ use proc_macro2::{Span, TokenStream}; use quote::{quote_spanned, ToTokens}; pub enum Deprecation { - PyClassTextSignature, PyMethodsNewDeprecatedForm, } impl Deprecation { fn ident(&self, span: Span) -> syn::Ident { let string = match self { - Deprecation::PyClassTextSignature => "PYCLASS_TEXT_SIGNATURE", Deprecation::PyMethodsNewDeprecatedForm => "PYMETHODS_NEW_DEPRECATED_FORM", }; syn::Ident::new(string, span) diff --git a/pyo3-macros-backend/src/pyclass.rs b/pyo3-macros-backend/src/pyclass.rs index e3988ec1..f037335e 100644 --- a/pyo3-macros-backend/src/pyclass.rs +++ b/pyo3-macros-backend/src/pyclass.rs @@ -6,7 +6,7 @@ use crate::attributes::{ ModuleAttribute, NameAttribute, NameLitStr, RenameAllAttribute, TextSignatureAttribute, TextSignatureAttributeValue, }; -use crate::deprecations::{Deprecation, Deprecations}; +use crate::deprecations::Deprecations; use crate::konst::{ConstAttributes, ConstSpec}; use crate::method::FnSpec; use crate::pyimpl::{gen_py_const, PyClassMethodsType}; @@ -34,7 +34,6 @@ pub enum PyClassKind { pub struct PyClassArgs { pub class_kind: PyClassKind, pub options: PyClassPyO3Options, - pub deprecations: Deprecations, } impl PyClassArgs { @@ -42,7 +41,6 @@ impl PyClassArgs { Ok(PyClassArgs { class_kind: kind, options: PyClassPyO3Options::parse(input)?, - deprecations: Deprecations::new(), }) } @@ -73,8 +71,6 @@ pub struct PyClassPyO3Options { pub text_signature: Option, pub unsendable: Option, pub weakref: Option, - - pub deprecations: Deprecations, } enum PyClassPyO3Option { @@ -91,7 +87,6 @@ enum PyClassPyO3Option { Sequence(kw::sequence), SetAll(kw::set_all), Subclass(kw::subclass), - TextSignature(TextSignatureAttribute), Unsendable(kw::unsendable), Weakref(kw::weakref), } @@ -125,8 +120,6 @@ impl Parse for PyClassPyO3Option { input.parse().map(PyClassPyO3Option::SetAll) } else if lookahead.peek(attributes::kw::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) { input.parse().map(PyClassPyO3Option::Unsendable) } else if lookahead.peek(attributes::kw::weakref) { @@ -181,11 +174,6 @@ impl PyClassPyO3Options { PyClassPyO3Option::Sequence(sequence) => set_option!(sequence), PyClassPyO3Option::SetAll(set_all) => set_option!(set_all), 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::Weakref(weakref) => set_option!(weakref), } @@ -355,7 +343,7 @@ fn impl_class( methods_type: PyClassMethodsType, krate: syn::Path, ) -> syn::Result { - 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( cls, @@ -989,8 +977,6 @@ impl<'a> PyClassImplsBuilder<'a> { let default_slot_defs = self.default_slots.iter().map(|slot| &slot.slot_def); let freelist_slots = self.freelist_slots(); - let deprecations = &self.attr.deprecations; - let class_mutability = if self.attr.options.frozen.is_some() { quote! { ImmutableChild @@ -1040,7 +1026,6 @@ impl<'a> PyClassImplsBuilder<'a> { fn items_iter() -> _pyo3::impl_::pyclass::PyClassItemsIter { use _pyo3::impl_::pyclass::*; let collector = PyClassImplCollector::::new(); - #deprecations; static INTRINSIC_ITEMS: PyClassItems = PyClassItems { methods: &[#(#default_method_defs),*], 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> { 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, || { let collector = PyClassImplCollector::::new(); build_pyclass_doc(<#cls as _pyo3::PyTypeInfo>::NAME, #doc, #deprecated_text_signature.or_else(|| collector.new_text_signature())) diff --git a/src/conversions/rust_decimal.rs b/src/conversions/rust_decimal.rs index cdc8fd05..173e5785 100644 --- a/src/conversions/rust_decimal.rs +++ b/src/conversions/rust_decimal.rs @@ -50,7 +50,7 @@ //! ``` use crate::exceptions::PyValueError; -use crate::once_cell::GILOnceCell; +use crate::sync::GILOnceCell; use crate::types::PyType; use crate::{intern, FromPyObject, IntoPy, Py, PyAny, PyObject, PyResult, Python, ToPyObject}; use rust_decimal::Decimal; diff --git a/src/conversions/std/array.rs b/src/conversions/std/array.rs index 302a4554..167f8070 100644 --- a/src/conversions/std/array.rs +++ b/src/conversions/std/array.rs @@ -10,8 +10,6 @@ where { fn into_py(self, py: Python<'_>) -> PyObject { 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 ptr = ffi::PyList_New(len); @@ -21,7 +19,7 @@ where // - its Drop cleans up the list if user code panics. let list: Py = 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(); #[cfg(not(Py_LIMITED_API))] diff --git a/src/impl_/deprecations.rs b/src/impl_/deprecations.rs index e941e6f5..6b9930ac 100644 --- a/src/impl_/deprecations.rs +++ b/src/impl_/deprecations.rs @@ -1,10 +1,4 @@ //! 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__]`")] pub const PYMETHODS_NEW_DEPRECATED_FORM: () = (); diff --git a/src/lib.rs b/src/lib.rs index 842fe705..762644f1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -427,15 +427,6 @@ pub mod type_object; pub mod types; 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 pub use crate::conversions::*; diff --git a/src/types/sequence.rs b/src/types/sequence.rs index 4772d7f1..80fd17a8 100644 --- a/src/types/sequence.rs +++ b/src/types/sequence.rs @@ -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. #[inline] 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 /// 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`. @@ -803,10 +789,6 @@ mod tests { let ob = v.to_object(py); let seq = ob.downcast::(py).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() .eq(PyList::new(py, ["f", "o", "o"])) .unwrap()); - #[allow(deprecated)] - { - assert!(seq.list().is_ok()); - } }); } @@ -839,10 +817,6 @@ mod tests { .unwrap() .eq(PyTuple::new(py, ["foo", "bar"])) .unwrap()); - #[allow(deprecated)] - { - assert!(seq.tuple().is_ok()); - } }); } @@ -853,10 +827,6 @@ mod tests { let ob = v.to_object(py); let seq = ob.downcast::(py).unwrap(); assert!(seq.to_tuple().unwrap().eq(PyTuple::new(py, &v)).unwrap()); - #[allow(deprecated)] - { - assert!(seq.tuple().is_ok()); - } }); } diff --git a/tests/test_text_signature.rs b/tests/test_text_signature.rs index 46c286b4..5b0491d9 100644 --- a/tests/test_text_signature.rs +++ b/tests/test_text_signature.rs @@ -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, c: i32) -> Self { - let _ = (a, b, c); - Self {} - } - } - - Python::with_gil(|py| { - let typeobj = py.get_type::(); - - 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, c: i32) -> Self { - let _ = (a, b, c); - Self {} - } - } - - Python::with_gil(|py| { - let typeobj = py.get_type::(); - - 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, c: i32) -> Self { - let _ = (a, b, c); - Self {} - } - } - - Python::with_gil(|py| { - let typeobj = py.get_type::(); - 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)'" - ); - }); - } -} diff --git a/tests/ui/deprecations.rs b/tests/ui/deprecations.rs index a62ea84f..4177dd6d 100644 --- a/tests/ui/deprecations.rs +++ b/tests/ui/deprecations.rs @@ -3,7 +3,6 @@ use pyo3::prelude::*; #[pyclass] -#[pyo3(text_signature = "()")] struct MyClass; #[pymethods] diff --git a/tests/ui/deprecations.stderr b/tests/ui/deprecations.stderr index d1b2c301..a857b5ee 100644 --- a/tests/ui/deprecations.stderr +++ b/tests/ui/deprecations.stderr @@ -1,7 +1,7 @@ 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 @@ -9,9 +9,3 @@ note: the lint level is defined here | 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 = "()")] - | ^^^^^^^^^^^^^^ diff --git a/tests/ui/invalid_pyclass_args.stderr b/tests/ui/invalid_pyclass_args.stderr index 859f0f40..5b2bd24d 100644 --- a/tests/ui/invalid_pyclass_args.stderr +++ b/tests/ui/invalid_pyclass_args.stderr @@ -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 | 3 | #[pyclass(extend=pyo3::types::PyDict)] @@ -46,7 +46,7 @@ error: expected string literal 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 | 27 | #[pyclass(weakrev)]