deprecations: remove items deprecated in PyO3 0.14

This commit is contained in:
David Hewitt 2021-11-19 13:33:56 +00:00
parent b0d957bc35
commit c9a4cd1f87
32 changed files with 54 additions and 755 deletions

View file

@ -14,6 +14,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Update `indoc` optional dependency to 1.0. [#2004](https://github.com/PyO3/pyo3/pull/2004)
- Update `paste` optional dependency to 1.0. [#2004](https://github.com/PyO3/pyo3/pull/2004)
## Removed
- Remove all functionality deprecated in PyO3 0.14. [#2007](https://github.com/PyO3/pyo3/pull/2007)
## [0.15.1] - 2021-11-19
### Added

View file

@ -865,7 +865,6 @@ impl pyo3::class::impl_::PyClassImpl for MyClass {
visitor(collector.py_class_descriptors());
visitor(collector.object_protocol_methods());
visitor(collector.async_protocol_methods());
visitor(collector.context_protocol_methods());
visitor(collector.descr_protocol_methods());
visitor(collector.mapping_protocol_methods());
visitor(collector.number_protocol_methods());

View file

@ -1,13 +1,10 @@
use syn::{
parse::{Parse, ParseStream},
punctuated::Punctuated,
spanned::Spanned,
token::Comma,
Attribute, ExprPath, Ident, LitStr, Result, Token,
};
use crate::deprecations::{Deprecation, Deprecations};
pub mod kw {
syn::custom_keyword!(annotation);
syn::custom_keyword!(attribute);
@ -113,66 +110,3 @@ pub fn take_pyo3_options<T: Parse>(attrs: &mut Vec<syn::Attribute>) -> Result<Ve
})?;
Ok(out)
}
pub fn get_deprecated_name_attribute(
attr: &syn::Attribute,
deprecations: &mut Deprecations,
) -> syn::Result<Option<NameAttribute>> {
match attr.parse_meta() {
Ok(syn::Meta::NameValue(syn::MetaNameValue {
path,
lit: syn::Lit::Str(s),
..
})) if path.is_ident("name") => {
deprecations.push(Deprecation::NameAttribute, attr.span());
Ok(Some(NameAttribute(s.parse()?)))
}
_ => Ok(None),
}
}
pub fn get_deprecated_text_signature_attribute(
attr: &syn::Attribute,
deprecations: &mut Deprecations,
) -> syn::Result<Option<TextSignatureAttribute>> {
match attr.parse_meta() {
Ok(syn::Meta::NameValue(syn::MetaNameValue {
path,
lit: syn::Lit::Str(lit),
..
})) if path.is_ident("text_signature") => {
let text_signature = TextSignatureAttribute {
kw: syn::parse_quote!(text_signature),
eq_token: syn::parse_quote!(=),
lit,
};
deprecations.push(
crate::deprecations::Deprecation::TextSignatureAttribute,
attr.span(),
);
Ok(Some(text_signature))
}
_ => Ok(None),
}
}
pub fn take_deprecated_text_signature_attribute(
attrs: &mut Vec<syn::Attribute>,
deprecations: &mut Deprecations,
) -> syn::Result<Option<TextSignatureAttribute>> {
let mut text_signature = None;
let mut attrs_out = Vec::with_capacity(attrs.len());
for attr in attrs.drain(..) {
if let Some(value) = get_deprecated_text_signature_attribute(&attr, deprecations)? {
ensure_spanned!(
text_signature.is_none(),
attr.span() => "text_signature attribute already specified previously"
);
text_signature = Some(value);
} else {
attrs_out.push(attr);
}
}
*attrs = attrs_out;
Ok(text_signature)
}

View file

@ -107,13 +107,6 @@ impl PyMethod {
can_coexist: true,
}
}
const fn new(name: &'static str, proto: &'static str) -> Self {
PyMethod {
name,
proto,
can_coexist: false,
}
}
}
/// Represents a slot definition.
@ -156,20 +149,13 @@ pub const OBJECT: Proto = Proto {
.has_self(),
MethodProto::new("__str__", "PyObjectStrProtocol").has_self(),
MethodProto::new("__repr__", "PyObjectReprProtocol").has_self(),
MethodProto::new("__format__", "PyObjectFormatProtocol")
.args(&["Format"])
.has_self(),
MethodProto::new("__hash__", "PyObjectHashProtocol").has_self(),
MethodProto::new("__bytes__", "PyObjectBytesProtocol").has_self(),
MethodProto::new("__richcmp__", "PyObjectRichcmpProtocol")
.args(&["Other"])
.has_self(),
MethodProto::new("__bool__", "PyObjectBoolProtocol").has_self(),
],
py_methods: &[
PyMethod::new("__format__", "FormatProtocolImpl"),
PyMethod::new("__bytes__", "BytesProtocolImpl"),
],
py_methods: &[],
slot_defs: &[
SlotDef::new(&["__str__"], "Py_tp_str", "str"),
SlotDef::new(&["__repr__"], "Py_tp_repr", "repr"),
@ -194,15 +180,8 @@ pub const ASYNC: Proto = Proto {
MethodProto::new("__await__", "PyAsyncAwaitProtocol").args(&["Receiver"]),
MethodProto::new("__aiter__", "PyAsyncAiterProtocol").args(&["Receiver"]),
MethodProto::new("__anext__", "PyAsyncAnextProtocol").args(&["Receiver"]),
MethodProto::new("__aenter__", "PyAsyncAenterProtocol").has_self(),
MethodProto::new("__aexit__", "PyAsyncAexitProtocol")
.args(&["ExcType", "ExcValue", "Traceback"])
.has_self(),
],
py_methods: &[
PyMethod::new("__aenter__", "PyAsyncAenterProtocolImpl"),
PyMethod::new("__aexit__", "PyAsyncAexitProtocolImpl"),
],
py_methods: &[],
slot_defs: &[
SlotDef::new(&["__await__"], "Py_am_await", "await_"),
SlotDef::new(&["__aiter__"], "Py_am_aiter", "aiter"),
@ -228,22 +207,6 @@ pub const BUFFER: Proto = Proto {
],
};
pub const CONTEXT: Proto = Proto {
name: "Context",
module: "::pyo3::class::context",
methods: &[
MethodProto::new("__enter__", "PyContextEnterProtocol").has_self(),
MethodProto::new("__exit__", "PyContextExitProtocol")
.args(&["ExcType", "ExcValue", "Traceback"])
.has_self(),
],
py_methods: &[
PyMethod::new("__enter__", "PyContextEnterProtocolImpl"),
PyMethod::new("__exit__", "PyContextExitProtocolImpl"),
],
slot_defs: &[],
};
pub const GC: Proto = Proto {
name: "GC",
module: "::pyo3::class::gc",
@ -268,17 +231,8 @@ pub const DESCR: Proto = Proto {
methods: &[
MethodProto::new("__get__", "PyDescrGetProtocol").args(&["Receiver", "Inst", "Owner"]),
MethodProto::new("__set__", "PyDescrSetProtocol").args(&["Receiver", "Inst", "Value"]),
MethodProto::new("__delete__", "PyDescrDelProtocol")
.args(&["Inst"])
.has_self(),
MethodProto::new("__set_name__", "PyDescrSetNameProtocol")
.args(&["Inst"])
.has_self(),
],
py_methods: &[
PyMethod::new("__delete__", "PyDescrDelProtocolImpl"),
PyMethod::new("__set_name__", "PyDescrNameProtocolImpl"),
],
py_methods: &[],
slot_defs: &[
SlotDef::new(&["__get__"], "Py_tp_descr_get", "descr_get"),
SlotDef::new(&["__set__"], "Py_tp_descr_set", "descr_set"),
@ -313,12 +267,8 @@ pub const MAPPING: Proto = Proto {
MethodProto::new("__delitem__", "PyMappingDelItemProtocol")
.args(&["Key"])
.has_self(),
MethodProto::new("__reversed__", "PyMappingReversedProtocol").has_self(),
],
py_methods: &[PyMethod::new(
"__reversed__",
"PyMappingReversedProtocolImpl",
)],
py_methods: &[],
slot_defs: &[
SlotDef::new(&["__len__"], "Py_mp_length", "len"),
SlotDef::new(&["__getitem__"], "Py_mp_subscript", "getitem"),
@ -492,13 +442,9 @@ pub const NUM: Proto = Proto {
MethodProto::new("__pos__", "PyNumberPosProtocol").has_self(),
MethodProto::new("__abs__", "PyNumberAbsProtocol").has_self(),
MethodProto::new("__invert__", "PyNumberInvertProtocol").has_self(),
MethodProto::new("__complex__", "PyNumberComplexProtocol").has_self(),
MethodProto::new("__int__", "PyNumberIntProtocol").has_self(),
MethodProto::new("__float__", "PyNumberFloatProtocol").has_self(),
MethodProto::new("__index__", "PyNumberIndexProtocol").has_self(),
MethodProto::new("__round__", "PyNumberRoundProtocol")
.args(&["NDigits"])
.has_self(),
],
py_methods: &[
PyMethod::coexist("__radd__", "PyNumberRAddProtocolImpl"),
@ -515,8 +461,6 @@ pub const NUM: Proto = Proto {
PyMethod::coexist("__rand__", "PyNumberRAndProtocolImpl"),
PyMethod::coexist("__rxor__", "PyNumberRXorProtocolImpl"),
PyMethod::coexist("__ror__", "PyNumberROrProtocolImpl"),
PyMethod::new("__complex__", "PyNumberComplexProtocolImpl"),
PyMethod::new("__round__", "PyNumberRoundProtocolImpl"),
],
slot_defs: &[
SlotDef::new(&["__add__", "__radd__"], "Py_nb_add", "add_radd"),

View file

@ -2,20 +2,12 @@ use proc_macro2::{Span, TokenStream};
use quote::{quote_spanned, ToTokens};
pub enum Deprecation {
NameAttribute,
PyfnNameArgument,
PyModuleNameArgument,
TextSignatureAttribute,
CallAttribute,
}
impl Deprecation {
fn ident(&self, span: Span) -> syn::Ident {
let string = match self {
Deprecation::NameAttribute => "NAME_ATTRIBUTE",
Deprecation::PyfnNameArgument => "PYFN_NAME_ARGUMENT",
Deprecation::PyModuleNameArgument => "PYMODULE_NAME_ARGUMENT",
Deprecation::TextSignatureAttribute => "TEXT_SIGNATURE_ATTRIBUTE",
Deprecation::CallAttribute => "CALL_ATTRIBUTE",
};
syn::Ident::new(string, span)

View file

@ -1,10 +1,7 @@
use std::borrow::Cow;
use crate::{
attributes::{
self, get_deprecated_name_attribute, get_pyo3_options, is_attribute_ident, take_attributes,
NameAttribute,
},
attributes::{self, get_pyo3_options, is_attribute_ident, take_attributes, NameAttribute},
deprecations::Deprecations,
};
use proc_macro2::{Ident, TokenStream};
@ -81,11 +78,6 @@ impl ConstAttributes {
}
}
Ok(true)
} else if let Some(name) =
get_deprecated_name_attribute(attr, &mut attributes.deprecations)?
{
attributes.set_name(name)?;
Ok(true)
} else {
Ok(false)
}

View file

@ -2,15 +2,10 @@
//! Code generation for the function that initializes a python module and adds classes and function.
use crate::{
attributes::{self, take_pyo3_options},
deprecations::Deprecations,
attributes::{self, is_attribute_ident, take_attributes, take_pyo3_options, NameAttribute},
pyfunction::{impl_wrap_pyfunction, PyFunctionOptions},
utils::PythonDoc,
};
use crate::{
attributes::{is_attribute_ident, take_attributes, NameAttribute},
deprecations::Deprecation,
};
use proc_macro2::{Span, TokenStream};
use quote::quote;
use syn::{
@ -23,23 +18,11 @@ use syn::{
pub struct PyModuleOptions {
name: Option<syn::Ident>,
deprecations: Deprecations,
}
impl PyModuleOptions {
pub fn from_pymodule_arg_and_attrs(
deprecated_pymodule_name_arg: Option<syn::Ident>,
attrs: &mut Vec<syn::Attribute>,
) -> Result<Self> {
let mut deprecations = Deprecations::new();
if let Some(name) = &deprecated_pymodule_name_arg {
deprecations.push(Deprecation::PyModuleNameArgument, name.span());
}
let mut options: PyModuleOptions = PyModuleOptions {
name: deprecated_pymodule_name_arg,
deprecations,
};
pub fn from_attrs(attrs: &mut Vec<syn::Attribute>) -> Result<Self> {
let mut options: PyModuleOptions = PyModuleOptions { name: None };
for option in take_pyo3_options(attrs)? {
match option {
@ -65,7 +48,6 @@ impl PyModuleOptions {
/// module
pub fn py_init(fnname: &Ident, options: PyModuleOptions, doc: PythonDoc) -> TokenStream {
let name = options.name.unwrap_or_else(|| fnname.unraw());
let deprecations = options.deprecations;
let cb_name = Ident::new(&format!("PyInit_{}", name), Span::call_site());
quote! {
@ -79,8 +61,6 @@ pub fn py_init(fnname: &Ident, options: PyModuleOptions, doc: PythonDoc) -> Toke
static DOC: &str = #doc;
static MODULE_DEF: ModuleDef = unsafe { ModuleDef::new(NAME, DOC) };
#deprecations
::pyo3::callback::handle_panic(|_py| { MODULE_DEF.make_module(_py, #fnname) })
}
}
@ -129,23 +109,10 @@ impl Parse for PyFnArgs {
let _: Comma = input.parse()?;
let mut deprecated_name_argument = None;
if let Ok(lit_str) = input.parse::<syn::LitStr>() {
deprecated_name_argument = Some(lit_str);
if !input.is_empty() {
let _: Comma = input.parse()?;
}
}
let mut options: PyFunctionOptions = input.parse()?;
if let Some(lit_str) = deprecated_name_argument {
options.set_name(NameAttribute(lit_str.parse()?))?;
options
.deprecations
.push(Deprecation::PyfnNameArgument, lit_str.span());
}
Ok(Self { modname, options })
Ok(Self {
modname,
options: input.parse()?,
})
}
}
@ -167,7 +134,9 @@ fn get_pyfn_attr(attrs: &mut Vec<syn::Attribute>) -> syn::Result<Option<PyFnArgs
})?;
if let Some(pyfn_args) = &mut pyfn_args {
pyfn_args.options.take_pyo3_options(attrs)?;
pyfn_args
.options
.add_attributes(take_pyo3_options(attrs)?)?;
}
Ok(pyfn_args)

View file

@ -1,9 +1,6 @@
// Copyright (c) 2017-present PyO3 Project and Contributors
use crate::attributes::{
self, take_deprecated_text_signature_attribute, take_pyo3_options, NameAttribute,
TextSignatureAttribute,
};
use crate::attributes::{self, take_pyo3_options, NameAttribute, TextSignatureAttribute};
use crate::deprecations::Deprecations;
use crate::pyimpl::PyClassMethodsType;
use crate::pymethod::{impl_py_getter_def, impl_py_setter_def, PropertyType};
@ -218,12 +215,7 @@ pub fn build_py_class(
args: &PyClassArgs,
methods_type: PyClassMethodsType,
) -> syn::Result<TokenStream> {
let mut options = PyClassPyO3Options::take_pyo3_options(&mut class.attrs)?;
if let Some(text_signature) =
take_deprecated_text_signature_attribute(&mut class.attrs, &mut options.deprecations)?
{
options.set_text_signature(text_signature)?;
}
let options = PyClassPyO3Options::take_pyo3_options(&mut class.attrs)?;
let doc = utils::get_doc(
&class.attrs,
options
@ -569,7 +561,6 @@ fn impl_class(
visitor(collector.py_class_descriptors());
visitor(collector.object_protocol_methods());
visitor(collector.async_protocol_methods());
visitor(collector.context_protocol_methods());
visitor(collector.descr_protocol_methods());
visitor(collector.mapping_protocol_methods());
visitor(collector.number_protocol_methods());

View file

@ -2,9 +2,8 @@
use crate::{
attributes::{
self, get_deprecated_name_attribute, get_deprecated_text_signature_attribute,
get_pyo3_options, take_attributes, FromPyWithAttribute, NameAttribute,
TextSignatureAttribute,
self, get_pyo3_options, take_attributes, take_pyo3_options, FromPyWithAttribute,
NameAttribute, TextSignatureAttribute,
},
deprecations::Deprecations,
method::{self, CallingConvention, FnArg},
@ -303,34 +302,10 @@ impl Parse for PyFunctionOption {
impl PyFunctionOptions {
pub fn from_attrs(attrs: &mut Vec<syn::Attribute>) -> syn::Result<Self> {
let mut options = PyFunctionOptions::default();
options.take_pyo3_options(attrs)?;
options.add_attributes(take_pyo3_options(attrs)?)?;
Ok(options)
}
pub fn take_pyo3_options(&mut self, attrs: &mut Vec<syn::Attribute>) -> syn::Result<()> {
take_attributes(attrs, |attr| {
if let Some(pyo3_attributes) = get_pyo3_options(attr)? {
self.add_attributes(pyo3_attributes)?;
Ok(true)
} else if let Some(name) = get_deprecated_name_attribute(attr, &mut self.deprecations)?
{
self.set_name(name)?;
Ok(true)
} else if let Some(text_signature) =
get_deprecated_text_signature_attribute(attr, &mut self.deprecations)?
{
self.add_attributes(std::iter::once(PyFunctionOption::TextSignature(
text_signature,
)))?;
Ok(true)
} else {
Ok(false)
}
})?;
Ok(())
}
pub fn add_attributes(
&mut self,
attrs: impl IntoIterator<Item = PyFunctionOption>,
@ -379,7 +354,7 @@ pub fn build_py_function(
ast: &mut syn::ItemFn,
mut options: PyFunctionOptions,
) -> syn::Result<TokenStream> {
options.take_pyo3_options(&mut ast.attrs)?;
options.add_attributes(take_pyo3_options(&mut ast.attrs)?)?;
Ok(impl_wrap_pyfunction(ast, options)?.1)
}

View file

@ -18,7 +18,6 @@ pub fn build_py_proto(ast: &mut syn::ItemImpl) -> syn::Result<TokenStream> {
Some(segment) if segment.ident == "PyAsyncProtocol" => &defs::ASYNC,
Some(segment) if segment.ident == "PyMappingProtocol" => &defs::MAPPING,
Some(segment) if segment.ident == "PyIterProtocol" => &defs::ITER,
Some(segment) if segment.ident == "PyContextProtocol" => &defs::CONTEXT,
Some(segment) if segment.ident == "PySequenceProtocol" => &defs::SEQ,
Some(segment) if segment.ident == "PyNumberProtocol" => &defs::NUM,
Some(segment) if segment.ident == "PyDescrProtocol" => &defs::DESCR,

View file

@ -12,7 +12,7 @@ use pyo3_macros_backend::{
PyFunctionOptions, PyModuleOptions,
};
use quote::quote;
use syn::parse_macro_input;
use syn::{parse::Nothing, parse_macro_input};
/// A proc macro used to implement Python modules.
///
@ -31,19 +31,11 @@ use syn::parse_macro_input;
///
/// [1]: https://pyo3.rs/latest/module.html
#[proc_macro_attribute]
pub fn pymodule(attr: TokenStream, input: TokenStream) -> TokenStream {
pub fn pymodule(args: TokenStream, input: TokenStream) -> TokenStream {
parse_macro_input!(args as Nothing);
let mut ast = parse_macro_input!(input as syn::ItemFn);
let deprecated_pymodule_name_arg = if attr.is_empty() {
None
} else {
Some(parse_macro_input!(attr as syn::Ident))
};
let options = match PyModuleOptions::from_pymodule_arg_and_attrs(
deprecated_pymodule_name_arg,
&mut ast.attrs,
) {
let options = match PyModuleOptions::from_attrs(&mut ast.attrs) {
Ok(options) => options,
Err(e) => return e.to_compile_error().into(),
};

View file

@ -81,17 +81,6 @@ pub trait PyObjectProtocol<'p>: PyClass {
unimplemented!()
}
#[deprecated(
since = "0.14.0",
note = "prefer implementing `__format__` in `#[pymethods]` instead of in a protocol"
)]
fn __format__(&'p self, format_spec: Self::Format) -> Self::Result
where
Self: PyObjectFormatProtocol<'p>,
{
unimplemented!()
}
fn __hash__(&'p self) -> Self::Result
where
Self: PyObjectHashProtocol<'p>,
@ -99,17 +88,6 @@ pub trait PyObjectProtocol<'p>: PyClass {
unimplemented!()
}
#[deprecated(
since = "0.14.0",
note = "prefer implementing `__bytes__` in `#[pymethods]` instead of in a protocol"
)]
fn __bytes__(&'p self) -> Self::Result
where
Self: PyObjectBytesProtocol<'p>,
{
unimplemented!()
}
fn __richcmp__(&'p self, other: Self::Other, op: CompareOp) -> Self::Result
where
Self: PyObjectRichcmpProtocol<'p>,
@ -143,19 +121,12 @@ pub trait PyObjectStrProtocol<'p>: PyObjectProtocol<'p> {
pub trait PyObjectReprProtocol<'p>: PyObjectProtocol<'p> {
type Result: IntoPyCallbackOutput<PyObject>;
}
pub trait PyObjectFormatProtocol<'p>: PyObjectProtocol<'p> {
type Format: FromPyObject<'p>;
type Result: IntoPyCallbackOutput<PyObject>;
}
pub trait PyObjectHashProtocol<'p>: PyObjectProtocol<'p> {
type Result: IntoPyCallbackOutput<HashCallbackOutput>;
}
pub trait PyObjectBoolProtocol<'p>: PyObjectProtocol<'p> {
type Result: IntoPyCallbackOutput<bool>;
}
pub trait PyObjectBytesProtocol<'p>: PyObjectProtocol<'p> {
type Result: IntoPyCallbackOutput<PyObject>;
}
pub trait PyObjectRichcmpProtocol<'p>: PyObjectProtocol<'p> {
type Other: FromPyObject<'p>;
type Result: IntoPyCallbackOutput<PyObject>;

View file

@ -1,49 +0,0 @@
// Copyright (c) 2017-present PyO3 Project and Contributors
//! Context manager api
//! Trait and support implementation for context manager api
use crate::callback::IntoPyCallbackOutput;
use crate::{PyClass, PyObject};
/// Context manager interface
#[allow(unused_variables)]
pub trait PyContextProtocol<'p>: PyClass {
#[deprecated(
since = "0.14.0",
note = "prefer implementing `__enter__` in `#[pymethods]` instead of in a protocol"
)]
fn __enter__(&'p mut self) -> Self::Result
where
Self: PyContextEnterProtocol<'p>,
{
unimplemented!()
}
#[deprecated(
since = "0.14.0",
note = "prefer implementing `__exit__` in `#[pymethods]` instead of in a protocol"
)]
fn __exit__(
&'p mut self,
exc_type: Option<Self::ExcType>,
exc_value: Option<Self::ExcValue>,
traceback: Option<Self::Traceback>,
) -> Self::Result
where
Self: PyContextExitProtocol<'p>,
{
unimplemented!()
}
}
pub trait PyContextEnterProtocol<'p>: PyContextProtocol<'p> {
type Result: IntoPyCallbackOutput<PyObject>;
}
pub trait PyContextExitProtocol<'p>: PyContextProtocol<'p> {
type ExcType: crate::FromPyObject<'p>;
type ExcValue: crate::FromPyObject<'p>;
type Traceback: crate::FromPyObject<'p>;
type Result: IntoPyCallbackOutput<PyObject>;
}

View file

@ -6,7 +6,6 @@
//! https://docs.python.org/3/reference/datamodel.html#implementing-descriptors)
use crate::callback::IntoPyCallbackOutput;
use crate::types::PyAny;
use crate::{FromPyObject, PyClass, PyObject};
use std::os::raw::c_int;
@ -30,28 +29,6 @@ pub trait PyDescrProtocol<'p>: PyClass {
{
unimplemented!()
}
#[deprecated(
since = "0.14.0",
note = "prefer implementing `__delete__` in `#[pymethods]` instead of in a protocol"
)]
fn __delete__(&'p self, instance: &'p PyAny) -> Self::Result
where
Self: PyDescrDeleteProtocol<'p>,
{
unimplemented!()
}
#[deprecated(
since = "0.14.0",
note = "prefer implementing `__set_name__` in `#[pymethods]` instead of in a protocol"
)]
fn __set_name__(&'p self, instance: &'p PyAny) -> Self::Result
where
Self: PyDescrSetNameProtocol<'p>,
{
unimplemented!()
}
}
pub trait PyDescrGetProtocol<'p>: PyDescrProtocol<'p> {
@ -68,15 +45,5 @@ pub trait PyDescrSetProtocol<'p>: PyDescrProtocol<'p> {
type Result: IntoPyCallbackOutput<()>;
}
pub trait PyDescrDeleteProtocol<'p>: PyDescrProtocol<'p> {
type Inst: FromPyObject<'p>;
type Result: IntoPyCallbackOutput<()>;
}
pub trait PyDescrSetNameProtocol<'p>: PyDescrProtocol<'p> {
type Inst: FromPyObject<'p>;
type Result: IntoPyCallbackOutput<()>;
}
py_ternarys_func!(descr_get, PyDescrGetProtocol, Self::__get__);
py_ternarys_func!(descr_set, PyDescrSetProtocol, Self::__set__, c_int);

View file

@ -670,7 +670,6 @@ slots_trait!(PyMethodsProtocolSlots, methods_protocol_slots);
methods_trait!(PyObjectProtocolMethods, object_protocol_methods);
methods_trait!(PyAsyncProtocolMethods, async_protocol_methods);
methods_trait!(PyContextProtocolMethods, context_protocol_methods);
methods_trait!(PyDescrProtocolMethods, descr_protocol_methods);
methods_trait!(PyMappingProtocolMethods, mapping_protocol_methods);
methods_trait!(PyNumberProtocolMethods, number_protocol_methods);

View file

@ -36,17 +36,6 @@ pub trait PyMappingProtocol<'p>: PyClass {
{
unimplemented!()
}
#[deprecated(
since = "0.14.0",
note = "prefer implementing `__reversed__` in `#[pymethods]` instead of in a protocol"
)]
fn __reversed__(&'p self) -> Self::Result
where
Self: PyMappingReversedProtocol<'p>,
{
unimplemented!()
}
}
// The following are a bunch of marker traits used to detect
@ -72,10 +61,6 @@ pub trait PyMappingDelItemProtocol<'p>: PyMappingProtocol<'p> {
type Result: IntoPyCallbackOutput<()>;
}
pub trait PyMappingReversedProtocol<'p>: PyMappingProtocol<'p> {
type Result: IntoPyCallbackOutput<PyObject>;
}
py_len_func!(len, PyMappingLenProtocol, Self::__len__);
py_binary_func!(getitem, PyMappingGetItemProtocol, Self::__getitem__);
py_func_set!(setitem, PyMappingSetItemProtocol, Self::__setitem__);

View file

@ -8,7 +8,6 @@ mod macros;
pub mod basic;
#[cfg(not(Py_LIMITED_API))]
pub mod buffer;
pub mod context;
pub mod descr;
pub mod gc;
#[doc(hidden)]
@ -24,7 +23,6 @@ pub mod sequence;
pub use self::basic::PyObjectProtocol;
#[cfg(not(Py_LIMITED_API))]
pub use self::buffer::PyBufferProtocol;
pub use self::context::PyContextProtocol;
pub use self::descr::PyDescrProtocol;
pub use self::gc::{PyGCProtocol, PyTraverseError, PyVisit};
pub use self::iter::PyIterProtocol;

View file

@ -283,16 +283,6 @@ pub trait PyNumberProtocol<'p>: PyClass {
{
unimplemented!()
}
#[deprecated(
since = "0.14.0",
note = "prefer implementing `__complex__` in `#[pymethods]` instead of in a protocol"
)]
fn __complex__(&'p self) -> Self::Result
where
Self: PyNumberComplexProtocol<'p>,
{
unimplemented!()
}
fn __int__(&'p self) -> Self::Result
where
Self: PyNumberIntProtocol<'p>,
@ -311,16 +301,6 @@ pub trait PyNumberProtocol<'p>: PyClass {
{
unimplemented!()
}
#[deprecated(
since = "0.14.0",
note = "prefer implementing `__round__` in `#[pymethods]` instead of in a protocol"
)]
fn __round__(&'p self, ndigits: Option<Self::NDigits>) -> Self::Result
where
Self: PyNumberRoundProtocol<'p>,
{
unimplemented!()
}
}
pub trait PyNumberAddProtocol<'p>: PyNumberProtocol<'p> {
@ -569,10 +549,6 @@ pub trait PyNumberInvertProtocol<'p>: PyNumberProtocol<'p> {
type Result: IntoPyCallbackOutput<PyObject>;
}
pub trait PyNumberComplexProtocol<'p>: PyNumberProtocol<'p> {
type Result: IntoPyCallbackOutput<PyObject>;
}
pub trait PyNumberIntProtocol<'p>: PyNumberProtocol<'p> {
type Result: IntoPyCallbackOutput<PyObject>;
}
@ -581,11 +557,6 @@ pub trait PyNumberFloatProtocol<'p>: PyNumberProtocol<'p> {
type Result: IntoPyCallbackOutput<PyObject>;
}
pub trait PyNumberRoundProtocol<'p>: PyNumberProtocol<'p> {
type NDigits: FromPyObject<'p>;
type Result: IntoPyCallbackOutput<PyObject>;
}
pub trait PyNumberIndexProtocol<'p>: PyNumberProtocol<'p> {
type Result: IntoPyCallbackOutput<PyObject>;
}

View file

@ -37,33 +37,6 @@ pub trait PyAsyncProtocol<'p>: PyClass {
{
unimplemented!()
}
#[deprecated(
since = "0.14.0",
note = "prefer implementing `__aenter__` in `#[pymethods]` instead of in a protocol"
)]
fn __aenter__(&'p mut self) -> Self::Result
where
Self: PyAsyncAenterProtocol<'p>,
{
unimplemented!()
}
#[deprecated(
since = "0.14.0",
note = "prefer implementing `__aexit__` in `#[pymethods]` instead of in a protocol"
)]
fn __aexit__(
&'p mut self,
exc_type: Option<Self::ExcType>,
exc_value: Option<Self::ExcValue>,
traceback: Option<Self::Traceback>,
) -> Self::Result
where
Self: PyAsyncAexitProtocol<'p>,
{
unimplemented!()
}
}
pub trait PyAsyncAwaitProtocol<'p>: PyAsyncProtocol<'p> {
@ -81,17 +54,6 @@ pub trait PyAsyncAnextProtocol<'p>: PyAsyncProtocol<'p> {
type Result: IntoPyCallbackOutput<PyIterANextOutput>;
}
pub trait PyAsyncAenterProtocol<'p>: PyAsyncProtocol<'p> {
type Result: IntoPyCallbackOutput<PyObject>;
}
pub trait PyAsyncAexitProtocol<'p>: PyAsyncProtocol<'p> {
type ExcType: crate::FromPyObject<'p>;
type ExcValue: crate::FromPyObject<'p>;
type Traceback: crate::FromPyObject<'p>;
type Result: IntoPyCallbackOutput<PyObject>;
}
py_unarys_func!(await_, PyAsyncAwaitProtocol, Self::__await__);
py_unarys_func!(aiter, PyAsyncAiterProtocol, Self::__aiter__);
py_unarys_func!(anext, PyAsyncAnextProtocol, Self::__anext__);

View file

@ -69,10 +69,7 @@ extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyImport_ReloadModule")]
pub fn PyImport_ReloadModule(m: *mut PyObject) -> *mut PyObject;
#[cfg(not(Py_3_9))]
#[deprecated(
since = "0.14.0",
note = "Removed in Python 3.9 as it was \"For internal use only\"."
)]
#[deprecated(note = "Removed in Python 3.9 as it was \"For internal use only\".")]
pub fn PyImport_Cleanup();
pub fn PyImport_ImportFrozenModuleObject(name: *mut PyObject) -> c_int;
pub fn PyImport_ImportFrozenModule(name: *const c_char) -> c_int;

View file

@ -4,10 +4,7 @@ extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyOS_InterruptOccurred")]
pub fn PyOS_InterruptOccurred() -> c_int;
#[cfg(not(Py_3_10))]
#[deprecated(
since = "0.14.0",
note = "Not documented in Python API; see Python 3.10 release notes"
)]
#[deprecated(note = "Not documented in Python API; see Python 3.10 release notes")]
pub fn PyOS_InitInterrupts();
#[cfg(any(not(Py_LIMITED_API), Py_3_7))]

View file

@ -1,28 +1,4 @@
//! Symbols used to denote deprecated usages of PyO3's proc macros.
#[deprecated(
since = "0.14.0",
note = "use `#[pyo3(name = \"...\")]` instead of `#[name = \"...\"]`"
)]
pub const NAME_ATTRIBUTE: () = ();
#[deprecated(
since = "0.14.0",
note = "use `#[pyfn(m)] #[pyo3(name = \"...\")]` instead of `#[pyfn(m, \"...\")]`"
)]
pub const PYFN_NAME_ARGUMENT: () = ();
#[deprecated(
since = "0.14.0",
note = "use `#[pymodule] #[pyo3(name = \"...\")]` instead of `#[pymodule(...)]`"
)]
pub const PYMODULE_NAME_ARGUMENT: () = ();
#[deprecated(
since = "0.14.0",
note = "use `#[pyo3(text_signature = \"...\")]` instead of `#[text_signature = \"...\"]`"
)]
pub const TEXT_SIGNATURE_ATTRIBUTE: () = ();
#[deprecated(since = "0.15.0", note = "use `fn __call__` instead of `#[call]`")]
pub const CALL_ATTRIBUTE: () = ();

View file

@ -8,9 +8,9 @@ use crate::exceptions;
use crate::ffi;
use crate::pyclass::PyClass;
use crate::type_object::PyTypeObject;
use crate::types::PyCFunction;
use crate::types::{PyAny, PyDict, PyList};
use crate::types::{PyCFunction, PyTuple};
use crate::{AsPyPointer, IntoPy, Py, PyObject, Python};
use crate::{AsPyPointer, IntoPy, PyObject, Python};
use std::ffi::{CStr, CString};
use std::str;
@ -367,46 +367,6 @@ impl PyModule {
let name = fun.getattr("__name__")?.extract()?;
self.add(name, fun)
}
/// Calls a function in the module.
///
/// This is equivalent to the Python expression `module.name(*args, **kwargs)`.
#[deprecated(
since = "0.14.0",
note = "use getattr(name)?.call(args, kwargs) instead"
)]
pub fn call(
&self,
name: &str,
args: impl IntoPy<Py<PyTuple>>,
kwargs: Option<&PyDict>,
) -> PyResult<&PyAny> {
self.getattr(name)?.call(args, kwargs)
}
/// Calls a function in the module with only positional arguments.
///
/// This is equivalent to the Python expression `module.name(*args)`.
#[deprecated(since = "0.14.0", note = "use getattr(name)?.call1(args) instead")]
pub fn call1(&self, name: &str, args: impl IntoPy<Py<PyTuple>>) -> PyResult<&PyAny> {
self.getattr(name)?.call1(args)
}
/// Calls a function in the module without arguments.
///
/// This is equivalent to the Python expression `module.name()`.
#[deprecated(since = "0.14.0", note = "use getattr(name)?.call0() instead")]
pub fn call0(&self, name: &str) -> PyResult<&PyAny> {
self.getattr(name)?.call0()
}
/// Gets a member from the module.
///
/// This is equivalent to the Python expression `module.name`.
#[deprecated(since = "0.14.0", note = "use getattr(name) instead")]
pub fn get(&self, name: &str) -> PyResult<&PyAny> {
self.getattr(name)
}
}
#[cfg(test)]

View file

@ -38,10 +38,6 @@ impl PyNumberProtocol for UnaryArithmetic {
fn __abs__(&self) -> Self {
Self::new(self.inner.abs())
}
fn __round__(&self, _ndigits: Option<u32>) -> Self {
Self::new(self.inner.round())
}
}
#[test]
@ -53,8 +49,6 @@ fn unary_arithmetic() {
py_run!(py, c, "assert repr(-c) == 'UA(-2.7)'");
py_run!(py, c, "assert repr(+c) == 'UA(2.7)'");
py_run!(py, c, "assert repr(abs(c)) == 'UA(2.7)'");
py_run!(py, c, "assert repr(round(c)) == 'UA(3)'");
py_run!(py, c, "assert repr(round(c, 1)) == 'UA(3)'");
}
#[pyclass]

View file

@ -22,6 +22,7 @@ fn _test_compile_errors() {
t.compile_fail("tests/ui/invalid_pyfunctions.rs");
t.compile_fail("tests/ui/invalid_pymethods.rs");
t.compile_fail("tests/ui/invalid_pymethod_names.rs");
t.compile_fail("tests/ui/invalid_pymodule_args.rs");
t.compile_fail("tests/ui/invalid_argument_attributes.rs");
t.compile_fail("tests/ui/missing_clone.rs");
t.compile_fail("tests/ui/reject_generics.rs");

View file

@ -1,5 +1,3 @@
#![allow(deprecated)] // for deprecated protocol methods
use std::collections::HashMap;
use pyo3::exceptions::PyKeyError;
@ -59,16 +57,6 @@ impl PyMappingProtocol for Mapping {
Ok(())
}
}
/// not an actual reversed implementation, just to demonstrate that the method is callable.
fn __reversed__(&self) -> PyObject {
let gil = Python::acquire_gil();
self.index
.keys()
.cloned()
.collect::<Vec<String>>()
.into_py(gil.python())
}
}
/// Return a dict with `m = Mapping(['1', '2', '3'])`.
@ -117,12 +105,3 @@ fn test_delitem() {
py_expect_exception!(py, *d, "del m[-1]", PyTypeError);
py_expect_exception!(py, *d, "del m['4']", PyKeyError);
}
#[test]
fn test_reversed() {
let gil = Python::acquire_gil();
let py = gil.python();
let d = map_dict(py);
py_assert!(py, *d, "set(reversed(m)) == {'1', '2', '3'}");
}

View file

@ -23,10 +23,6 @@ impl ValueClass {
#[pyclass(module = "module")]
struct LocatedClass {}
fn sum_as_string(a: i64, b: i64) -> String {
format!("{}", a + b)
}
#[pyfunction]
/// Doubles the given value
fn double(x: usize) -> usize {
@ -36,12 +32,6 @@ fn double(x: usize) -> usize {
/// This module is implemented in Rust.
#[pymodule]
fn module_with_functions(_py: Python, m: &PyModule) -> PyResult<()> {
#![allow(deprecated)]
#[pyfn(m, "sum_as_string")]
fn function_with_deprecated_name(_py: Python, a: i64, b: i64) -> String {
sum_as_string(a, b)
}
#[pyfn(m)]
#[pyo3(name = "no_parameters")]
fn function_with_name() -> usize {
@ -89,7 +79,6 @@ fn test_module_with_functions() {
*d,
"module_with_functions.__doc__ == 'This module is implemented in Rust.'"
);
py_assert!(py, *d, "module_with_functions.sum_as_string(1, 2) == '3'");
py_assert!(py, *d, "module_with_functions.no_parameters() == 42");
py_assert!(py, *d, "module_with_functions.foo == 'bar'");
py_assert!(py, *d, "module_with_functions.AnonClass != None");
@ -438,20 +427,6 @@ fn test_module_functions_with_module() {
);
}
#[test]
#[allow(deprecated)]
fn test_module_with_deprecated_name() {
#[pymodule(custom_name)]
fn my_module(_py: Python, _m: &PyModule) -> PyResult<()> {
Ok(())
}
Python::with_gil(|py| {
let m = pyo3::wrap_pymodule!(custom_name)(py);
py_assert!(py, m, "m.__name__ == 'custom_name'");
})
}
#[test]
fn test_module_doc_hidden() {
#[doc(hidden)]

View file

@ -1,8 +1,6 @@
#![allow(deprecated)] // for deprecated protocol methods
use pyo3::class::{
PyAsyncProtocol, PyContextProtocol, PyDescrProtocol, PyIterProtocol, PyMappingProtocol,
PyObjectProtocol, PySequenceProtocol,
PyAsyncProtocol, PyDescrProtocol, PyIterProtocol, PyMappingProtocol, PyObjectProtocol,
PySequenceProtocol,
};
use pyo3::exceptions::{PyIndexError, PyValueError};
use pyo3::prelude::*;
@ -91,14 +89,6 @@ impl PyObjectProtocol for StringMethods {
fn __repr__(&self) -> &'static str {
"repr"
}
fn __format__(&self, format_spec: String) -> String {
format!("format({})", format_spec)
}
fn __bytes__(&self) -> &'static [u8] {
b"bytes"
}
}
#[test]
@ -109,12 +99,6 @@ fn string_methods() {
let obj = Py::new(py, StringMethods {}).unwrap();
py_assert!(py, obj, "str(obj) == 'str'");
py_assert!(py, obj, "repr(obj) == 'repr'");
py_assert!(py, obj, "'{0:x}'.format(obj) == 'format(x)'");
py_assert!(py, obj, "bytes(obj) == b'bytes'");
// Test that `__bytes__` takes no arguments (should be METH_NOARGS)
py_assert!(py, obj, "obj.__bytes__() == b'bytes'");
py_expect_exception!(py, obj, "obj.__bytes__('unexpected argument')", PyTypeError);
}
#[pyclass]
@ -298,25 +282,6 @@ fn setdelitem() {
assert_eq!(c.val, None);
}
#[pyclass]
struct Reversed {}
#[pyproto]
impl PyMappingProtocol for Reversed {
fn __reversed__(&self) -> &'static str {
"I am reversed"
}
}
#[test]
fn reversed() {
let gil = Python::acquire_gil();
let py = gil.python();
let c = Py::new(py, Reversed {}).unwrap();
py_run!(py, c, "assert reversed(c) == 'I am reversed'");
}
#[pyclass]
struct Contains {}
@ -338,57 +303,6 @@ fn contains() {
py_expect_exception!(py, c, "assert 'wrong type' not in c", PyTypeError);
}
#[pyclass]
struct ContextManager {
exit_called: bool,
}
#[pyproto]
impl PyContextProtocol for ContextManager {
fn __enter__(&mut self) -> i32 {
42
}
fn __exit__(
&mut self,
ty: Option<&PyType>,
_value: Option<&PyAny>,
_traceback: Option<&PyAny>,
) -> bool {
let gil = Python::acquire_gil();
self.exit_called = true;
ty == Some(gil.python().get_type::<PyValueError>())
}
}
#[test]
fn context_manager() {
let gil = Python::acquire_gil();
let py = gil.python();
let c = PyCell::new(py, ContextManager { exit_called: false }).unwrap();
py_run!(py, c, "with c as x: assert x == 42");
{
let mut c = c.borrow_mut();
assert!(c.exit_called);
c.exit_called = false;
}
py_run!(py, c, "with c as x: raise ValueError");
{
let mut c = c.borrow_mut();
assert!(c.exit_called);
c.exit_called = false;
}
py_expect_exception!(
py,
c,
"with c as x: raise NotImplementedError",
PyNotImplementedError
);
let c = c.borrow();
assert!(c.exit_called);
}
#[test]
fn test_basics() {
let gil = Python::acquire_gil();

View file

@ -2,28 +2,6 @@
use pyo3::prelude::*;
#[pyclass]
#[text_signature = "()"]
struct TestClass {
num: u32,
}
#[pymethods]
impl TestClass {
#[classattr]
#[name = "num"]
const DEPRECATED_NAME_CONSTANT: i32 = 0;
#[name = "num"]
#[text_signature = "()"]
fn deprecated_name_pymethod(&self) { }
#[staticmethod]
#[name = "custom_static"]
#[text_signature = "()"]
fn deprecated_name_staticmethod() {}
}
#[pyclass]
struct DeprecatedCall;
@ -33,20 +11,6 @@ impl DeprecatedCall {
fn deprecated_call(&self) {}
}
#[pyfunction]
#[name = "foo"]
#[text_signature = "()"]
fn deprecated_name_pyfunction() { }
#[pymodule(deprecated_module_name)]
fn my_module(_py: Python, m: &PyModule) -> PyResult<()> {
#[pyfn(m, "some_name")]
#[text_signature = "()"]
fn deprecated_name_pyfn() { }
Ok(())
}
fn main() {
}

View file

@ -1,77 +1,11 @@
error: use of deprecated constant `pyo3::impl_::deprecations::NAME_ATTRIBUTE`: use `#[pyo3(name = "...")]` instead of `#[name = "..."]`
--> tests/ui/deprecations.rs:14:5
error: use of deprecated constant `pyo3::impl_::deprecations::CALL_ATTRIBUTE`: use `fn __call__` instead of `#[call]`
--> tests/ui/deprecations.rs:10:7
|
14 | #[name = "num"]
| ^
10 | #[call]
| ^^^^
|
note: the lint level is defined here
--> tests/ui/deprecations.rs:1:9
|
1 | #![deny(deprecated)]
| ^^^^^^^^^^
error: use of deprecated constant `pyo3::impl_::deprecations::NAME_ATTRIBUTE`: use `#[pyo3(name = "...")]` instead of `#[name = "..."]`
--> tests/ui/deprecations.rs:17:5
|
17 | #[name = "num"]
| ^
error: use of deprecated constant `pyo3::impl_::deprecations::TEXT_SIGNATURE_ATTRIBUTE`: use `#[pyo3(text_signature = "...")]` instead of `#[text_signature = "..."]`
--> tests/ui/deprecations.rs:18:5
|
18 | #[text_signature = "()"]
| ^
error: use of deprecated constant `pyo3::impl_::deprecations::NAME_ATTRIBUTE`: use `#[pyo3(name = "...")]` instead of `#[name = "..."]`
--> tests/ui/deprecations.rs:22:5
|
22 | #[name = "custom_static"]
| ^
error: use of deprecated constant `pyo3::impl_::deprecations::TEXT_SIGNATURE_ATTRIBUTE`: use `#[pyo3(text_signature = "...")]` instead of `#[text_signature = "..."]`
--> tests/ui/deprecations.rs:23:5
|
23 | #[text_signature = "()"]
| ^
error: use of deprecated constant `pyo3::impl_::deprecations::CALL_ATTRIBUTE`: use `fn __call__` instead of `#[call]`
--> tests/ui/deprecations.rs:32:7
|
32 | #[call]
| ^^^^
error: use of deprecated constant `pyo3::impl_::deprecations::NAME_ATTRIBUTE`: use `#[pyo3(name = "...")]` instead of `#[name = "..."]`
--> tests/ui/deprecations.rs:37:1
|
37 | #[name = "foo"]
| ^
error: use of deprecated constant `pyo3::impl_::deprecations::TEXT_SIGNATURE_ATTRIBUTE`: use `#[pyo3(text_signature = "...")]` instead of `#[text_signature = "..."]`
--> tests/ui/deprecations.rs:38:1
|
38 | #[text_signature = "()"]
| ^
error: use of deprecated constant `pyo3::impl_::deprecations::PYFN_NAME_ARGUMENT`: use `#[pyfn(m)] #[pyo3(name = "...")]` instead of `#[pyfn(m, "...")]`
--> tests/ui/deprecations.rs:43:15
|
43 | #[pyfn(m, "some_name")]
| ^^^^^^^^^^^
error: use of deprecated constant `pyo3::impl_::deprecations::TEXT_SIGNATURE_ATTRIBUTE`: use `#[pyo3(text_signature = "...")]` instead of `#[text_signature = "..."]`
--> tests/ui/deprecations.rs:44:5
|
44 | #[text_signature = "()"]
| ^
error: use of deprecated constant `pyo3::impl_::deprecations::PYMODULE_NAME_ARGUMENT`: use `#[pymodule] #[pyo3(name = "...")]` instead of `#[pymodule(...)]`
--> tests/ui/deprecations.rs:41:12
|
41 | #[pymodule(deprecated_module_name)]
| ^^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated constant `pyo3::impl_::deprecations::TEXT_SIGNATURE_ATTRIBUTE`: use `#[pyo3(text_signature = "...")]` instead of `#[text_signature = "..."]`
--> tests/ui/deprecations.rs:6:1
|
6 | #[text_signature = "()"]
| ^

View file

@ -0,0 +1,8 @@
use pyo3::prelude::*;
#[pymodule(some_arg)]
fn module(_py: Python, m: &PyModule) -> PyResult<()> {
Ok(())
}
fn main(){}

View file

@ -0,0 +1,5 @@
error: unexpected token
--> tests/ui/invalid_pymodule_args.rs:3:12
|
3 | #[pymodule(some_arg)]
| ^^^^^^^^