Merge pull request #1272 from davidhewitt/bump-msrv

msrv: bump to 1.45
This commit is contained in:
David Hewitt 2020-11-12 18:33:23 +00:00 committed by GitHub
commit 519fd6188a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 121 additions and 148 deletions

View File

@ -58,7 +58,7 @@ jobs:
platform: { os: "windows-latest" }
include:
# Test minimal supported Rust version
- rust: 1.39.0
- rust: 1.45.0
python-version: 3.9
platform: { os: "ubuntu-latest", python-architecture: "x64", rust-target: "x86_64-unknown-linux-gnu" }
msrv: "MSRV"

View File

@ -8,6 +8,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [Unreleased]
### Packaging
- Drop support for Python 3.5 (as it is now end-of-life). [#1250](https://github.com/PyO3/pyo3/pull/1250)
- Bump minimum supported Rust version to 1.45. [#1272](https://github.com/PyO3/pyo3/pull/1272)
- Bump indoc dependency to 1.0. [#1272](https://github.com/PyO3/pyo3/pull/1272)
- Bump paste dependency to 1.0. [#1272](https://github.com/PyO3/pyo3/pull/1272)
### Added
- Add support for building for CPython limited API. This required a few minor changes to runtime behaviour of of pyo3 `#[pyclass]` types. See the migration guide for full details. [#1152](https://github.com/PyO3/pyo3/pull/1152)

View File

@ -16,13 +16,13 @@ edition = "2018"
[dependencies]
ctor = { version = "0.1", optional = true }
indoc = { version = "0.3.4", optional = true }
indoc = { version = "1.0.3", optional = true }
inventory = { version = "0.1.4", optional = true }
libc = "0.2.62"
parking_lot = "0.11.0"
num-bigint = { version = "0.3", optional = true }
num-complex = { version = "0.3", optional = true }
paste = { version = "0.1.6", optional = true }
paste = { version = "1.0.3", optional = true }
pyo3cls = { path = "pyo3cls", version = "=0.12.3", optional = true }
unindent = { version = "0.1.4", optional = true }
hashbrown = { version = "0.9", optional = true }

View File

@ -3,7 +3,7 @@
[![Actions Status](https://github.com/PyO3/pyo3/workflows/Test/badge.svg)](https://github.com/PyO3/pyo3/actions)
[![codecov](https://codecov.io/gh/PyO3/pyo3/branch/master/graph/badge.svg)](https://codecov.io/gh/PyO3/pyo3)
[![crates.io](http://meritbadge.herokuapp.com/pyo3)](https://crates.io/crates/pyo3)
[![minimum rustc 1.39](https://img.shields.io/badge/rustc-1.39+-blue.svg)](https://rust-lang.github.io/rfcs/2495-min-rust-version.html)
[![minimum rustc 1.45](https://img.shields.io/badge/rustc-1.45+-blue.svg)](https://rust-lang.github.io/rfcs/2495-min-rust-version.html)
[![Join the dev chat](https://img.shields.io/gitter/room/nwjs/nw.js.svg)](https://gitter.im/PyO3/Lobby)
[Rust](http://www.rust-lang.org/) bindings for [Python](https://www.python.org/). This includes running and interacting with Python code from a Rust binary, as well as writing native Python modules.
@ -18,7 +18,7 @@ A comparison with rust-cpython can be found [in the guide](https://pyo3.rs/maste
## Usage
PyO3 supports Python 3.6 and up. The minimum required Rust version is 1.39.0.
PyO3 supports Python 3.6 and up. The minimum required Rust version is 1.45.0.
Building with PyPy is also possible (via cpyext) for Python 3.6, targeted PyPy version is 7.3+.
Please refer to the [pypy section in the guide](https://pyo3.rs/master/pypy.html).

View File

@ -341,16 +341,16 @@ fn find_sysconfigdata(cross: &CrossCompileConfig) -> Result<PathBuf> {
/// recursive search for _sysconfigdata, returns all possibilities of sysconfigdata paths
fn search_lib_dir(path: impl AsRef<Path>, cross: &CrossCompileConfig) -> Vec<PathBuf> {
let mut sysconfig_paths = vec![];
let version_pat = if let Some(ref v) = cross.version {
let version_pat = if let Some(v) = &cross.version {
format!("python{}", v)
} else {
"python3.".into()
};
for f in fs::read_dir(path).expect("Path does not exist") {
let sysc = match f {
Ok(ref f) if starts_with(f, "_sysconfigdata") && ends_with(f, "py") => vec![f.path()],
Ok(ref f) if starts_with(f, "build") => search_lib_dir(f.path(), cross),
Ok(ref f) if starts_with(f, "lib.") => {
let sysc = match &f {
Ok(f) if starts_with(f, "_sysconfigdata") && ends_with(f, "py") => vec![f.path()],
Ok(f) if starts_with(f, "build") => search_lib_dir(f.path(), cross),
Ok(f) if starts_with(f, "lib.") => {
let name = f.file_name();
// check if right target os
if !name.to_string_lossy().contains(if cross.os == "android" {
@ -366,7 +366,7 @@ fn search_lib_dir(path: impl AsRef<Path>, cross: &CrossCompileConfig) -> Vec<Pat
}
search_lib_dir(f.path(), cross)
}
Ok(ref f) if starts_with(f, &version_pat) => search_lib_dir(f.path(), cross),
Ok(f) if starts_with(f, &version_pat) => search_lib_dir(f.path(), cross),
_ => continue,
};
sysconfig_paths.extend(sysc);
@ -569,7 +569,7 @@ fn run_python_script(interpreter: &Path, script: &str) -> Result<String> {
);
}
}
Ok(ref ok) if !ok.status.success() => bail!("Python script failed: {}"),
Ok(ok) if !ok.status.success() => bail!("Python script failed: {}"),
Ok(ok) => Ok(String::from_utf8(ok.stdout)?),
}
}

View File

@ -175,7 +175,7 @@ struct ClassWithGCSupport {
#[pyproto]
impl PyGCProtocol for ClassWithGCSupport {
fn __traverse__(&self, visit: PyVisit) -> Result<(), PyTraverseError> {
if let Some(ref obj) = self.obj {
if let Some(obj) = &self.obj {
visit.call(obj)?
}
Ok(())

View File

@ -137,13 +137,10 @@ impl<'a> Container<'a> {
}
let style = match (fields, transparent) {
(Fields::Unnamed(_), true) => ContainerType::TupleNewtype,
(Fields::Unnamed(unnamed), false) => {
if unnamed.unnamed.len() == 1 {
ContainerType::TupleNewtype
} else {
ContainerType::Tuple(unnamed.unnamed.len())
}
}
(Fields::Unnamed(unnamed), false) => match unnamed.unnamed.len() {
1 => ContainerType::TupleNewtype,
len => ContainerType::Tuple(len),
},
(Fields::Named(named), true) => {
let field = named
.named
@ -457,14 +454,15 @@ fn get_pyo3_meta_list(attrs: &[Attribute]) -> Result<MetaList> {
}
fn verify_and_get_lifetime(generics: &syn::Generics) -> Result<Option<&syn::LifetimeDef>> {
let lifetimes = generics.lifetimes().collect::<Vec<_>>();
if lifetimes.len() > 1 {
let mut lifetimes = generics.lifetimes();
let lifetime = lifetimes.next();
if lifetimes.next().is_some() {
return Err(spanned_err(
&generics,
"FromPyObject can be derived with at most one lifetime parameter.",
));
}
Ok(lifetimes.into_iter().next())
Ok(lifetime)
}
/// Derive FromPyObject for enums and structs.

View File

@ -100,7 +100,7 @@ pub struct FnSpec<'a> {
pub fn get_return_info(output: &syn::ReturnType) -> syn::Type {
match output {
syn::ReturnType::Default => syn::Type::Infer(syn::parse_quote! {_}),
syn::ReturnType::Type(_, ref ty) => *ty.clone(),
syn::ReturnType::Type(_, ty) => *ty.clone(),
}
}
@ -109,7 +109,7 @@ pub fn parse_method_receiver(arg: &syn::FnArg) -> syn::Result<SelfType> {
syn::FnArg::Receiver(recv) => Ok(SelfType::Receiver {
mutable: recv.mutability.is_some(),
}),
syn::FnArg::Typed(syn::PatType { ref ty, .. }) => Ok(SelfType::TryFromPyCell(ty.span())),
syn::FnArg::Typed(syn::PatType { ty, .. }) => Ok(SelfType::TryFromPyCell(ty.span())),
}
}
@ -198,14 +198,12 @@ impl<'a> FnSpec<'a> {
"Unexpected receiver for method",
));
}
syn::FnArg::Typed(syn::PatType {
ref pat, ref ty, ..
}) => {
let (ident, by_ref, mutability) = match **pat {
syn::FnArg::Typed(syn::PatType { pat, ty, .. }) => {
let (ident, by_ref, mutability) = match &**pat {
syn::Pat::Ident(syn::PatIdent {
ref ident,
ref by_ref,
ref mutability,
ident,
by_ref,
mutability,
..
}) => (ident, by_ref, mutability),
_ => {
@ -267,7 +265,7 @@ impl<'a> FnSpec<'a> {
pub fn is_args(&self, name: &syn::Ident) -> bool {
for s in self.attrs.iter() {
if let Argument::VarArgs(ref path) = s {
if let Argument::VarArgs(path) = s {
return path.is_ident(name);
}
}
@ -276,7 +274,7 @@ impl<'a> FnSpec<'a> {
pub fn is_kwargs(&self, name: &syn::Ident) -> bool {
for s in self.attrs.iter() {
if let Argument::KeywordArgs(ref path) = s {
if let Argument::KeywordArgs(path) = s {
return path.is_ident(name);
}
}
@ -285,10 +283,10 @@ impl<'a> FnSpec<'a> {
pub fn default_value(&self, name: &syn::Ident) -> Option<TokenStream> {
for s in self.attrs.iter() {
match *s {
Argument::Arg(ref path, ref opt) | Argument::Kwarg(ref path, ref opt) => {
match s {
Argument::Arg(path, opt) | Argument::Kwarg(path, opt) => {
if path.is_ident(name) {
if let Some(ref val) = opt {
if let Some(val) = opt {
let i: syn::Expr = syn::parse_str(&val).unwrap();
return Some(i.into_token_stream());
}
@ -302,7 +300,7 @@ impl<'a> FnSpec<'a> {
pub fn is_kw_only(&self, name: &syn::Ident) -> bool {
for s in self.attrs.iter() {
if let Argument::Kwarg(ref path, _) = s {
if let Argument::Kwarg(path, _) = s {
if path.is_ident(name) {
return true;
}
@ -341,7 +339,7 @@ fn parse_method_attributes(
for attr in attrs.iter() {
match attr.parse_meta()? {
syn::Meta::Path(ref name) => {
syn::Meta::Path(name) => {
if name.is_ident("new") || name.is_ident("__new__") {
set_ty!(MethodTypeAttribute::New, name);
} else if name.is_ident("init") || name.is_ident("__init__") {
@ -373,11 +371,7 @@ fn parse_method_attributes(
new_attrs.push(attr.clone())
}
}
syn::Meta::List(syn::MetaList {
ref path,
ref nested,
..
}) => {
syn::Meta::List(syn::MetaList { path, nested, .. }) => {
if path.is_ident("new") {
set_ty!(MethodTypeAttribute::New, path);
} else if path.is_ident("init") {
@ -408,11 +402,11 @@ fn parse_method_attributes(
};
property_name = match nested.first().unwrap() {
syn::NestedMeta::Meta(syn::Meta::Path(ref w)) if w.segments.len() == 1 => {
syn::NestedMeta::Meta(syn::Meta::Path(w)) if w.segments.len() == 1 => {
Some(w.segments[0].ident.clone())
}
syn::NestedMeta::Lit(ref lit) => match *lit {
syn::Lit::Str(ref s) => Some(s.parse()?),
syn::NestedMeta::Lit(lit) => match lit {
syn::Lit::Str(s) => Some(s.parse()?),
_ => {
return Err(syn::Error::new_spanned(
lit,
@ -428,7 +422,7 @@ fn parse_method_attributes(
}
};
} else if path.is_ident("args") {
let attrs = PyFunctionAttr::from_meta(nested)?;
let attrs = PyFunctionAttr::from_meta(&nested)?;
args.extend(attrs.arguments)
} else {
new_attrs.push(attr.clone())

View File

@ -35,7 +35,7 @@ pub fn process_functions_in_module(func: &mut syn::ItemFn) -> syn::Result<()> {
let mut stmts: Vec<syn::Stmt> = Vec::new();
for stmt in func.block.stmts.iter_mut() {
if let syn::Stmt::Item(syn::Item::Fn(ref mut func)) = stmt {
if let syn::Stmt::Item(syn::Item::Fn(func)) = stmt {
if let Some((module_name, python_name, pyfn_attrs)) =
extract_pyfn_attrs(&mut func.attrs)?
{
@ -59,8 +59,8 @@ pub fn process_functions_in_module(func: &mut syn::ItemFn) -> syn::Result<()> {
/// Transforms a rust fn arg parsed with syn into a method::FnArg
fn wrap_fn_argument<'a>(cap: &'a syn::PatType) -> syn::Result<method::FnArg<'a>> {
let (mutability, by_ref, ident) = match *cap.pat {
syn::Pat::Ident(ref patid) => (&patid.mutability, &patid.by_ref, &patid.ident),
let (mutability, by_ref, ident) = match &*cap.pat {
syn::Pat::Ident(patid) => (&patid.mutability, &patid.by_ref, &patid.ident),
_ => return Err(syn::Error::new_spanned(&cap.pat, "Unsupported argument")),
};
@ -85,12 +85,12 @@ fn extract_pyfn_attrs(
for attr in attrs.iter() {
match attr.parse_meta() {
Ok(syn::Meta::List(ref list)) if list.path.is_ident("pyfn") => {
Ok(syn::Meta::List(list)) if list.path.is_ident("pyfn") => {
let meta: Vec<_> = list.nested.iter().cloned().collect();
if meta.len() >= 2 {
// read module name
match meta[0] {
syn::NestedMeta::Meta(syn::Meta::Path(ref path)) => {
match &meta[0] {
syn::NestedMeta::Meta(syn::Meta::Path(path)) => {
modname = Some(path.clone())
}
_ => {
@ -101,8 +101,8 @@ fn extract_pyfn_attrs(
}
}
// read Python function name
match meta[1] {
syn::NestedMeta::Lit(syn::Lit::Str(ref lits)) => {
match &meta[1] {
syn::NestedMeta::Lit(syn::Lit::Str(lits)) => {
fnname = Some(syn::Ident::new(&lits.value(), lits.span()));
}
_ => {
@ -157,7 +157,7 @@ pub fn add_fn_to_module(
"Unexpected receiver for #[pyfn]",
))
}
syn::FnArg::Typed(ref cap) => {
syn::FnArg::Typed(cap) => {
if pyfn_attrs.pass_module && i == 0 {
if let syn::Type::Reference(tyref) = cap.ty.as_ref() {
if let syn::Type::Path(typath) = tyref.elem.as_ref() {

View File

@ -56,8 +56,8 @@ impl PyClassArgs {
/// either a single word or an assignment expression
fn add_expr(&mut self, expr: &Expr) -> syn::parse::Result<()> {
match expr {
syn::Expr::Path(ref exp) if exp.path.segments.len() == 1 => self.add_path(exp),
syn::Expr::Assign(ref assign) => self.add_assign(assign),
syn::Expr::Path(exp) if exp.path.segments.len() == 1 => self.add_path(exp),
syn::Expr::Assign(assign) => self.add_assign(assign),
_ => Err(syn::Error::new_spanned(expr, "Failed to parse arguments")),
}
}
@ -156,7 +156,7 @@ pub fn build_py_class(class: &mut syn::ItemStruct, attr: &PyClassArgs) -> syn::R
let mut descriptors = Vec::new();
check_generics(class)?;
if let syn::Fields::Named(ref mut fields) = class.fields {
if let syn::Fields::Named(fields) = &mut class.fields {
for field in fields.named.iter_mut() {
let field_descs = parse_descriptors(field)?;
if !field_descs.is_empty() {
@ -178,10 +178,10 @@ fn parse_descriptors(item: &mut syn::Field) -> syn::Result<Vec<FnType>> {
let mut descs = Vec::new();
let mut new_attrs = Vec::new();
for attr in item.attrs.iter() {
if let Ok(syn::Meta::List(ref list)) = attr.parse_meta() {
if let Ok(syn::Meta::List(list)) = attr.parse_meta() {
if list.path.is_ident("pyo3") {
for meta in list.nested.iter() {
if let syn::NestedMeta::Meta(ref metaitem) = meta {
if let syn::NestedMeta::Meta(metaitem) = meta {
if metaitem.path().is_ident("get") {
descs.push(FnType::Getter(SelfType::Receiver { mutable: false }));
} else if metaitem.path().is_ident("set") {
@ -318,7 +318,7 @@ fn impl_class(
let mut has_dict = false;
let mut has_gc = false;
for f in attr.flags.iter() {
if let syn::Expr::Path(ref epath) = f {
if let syn::Expr::Path(epath) = f {
if epath.path == parse_quote! { pyo3::type_flags::WEAKREF } {
has_weakref = true;
} else if epath.path == parse_quote! { pyo3::type_flags::DICT } {
@ -469,7 +469,7 @@ fn impl_descriptors(
) -> syn::Result<TokenStream> {
let py_methods: Vec<TokenStream> = descriptors
.iter()
.flat_map(|&(ref field, ref fns)| {
.flat_map(|(field, fns)| {
fns.iter()
.map(|desc| {
let name = field.ident.as_ref().unwrap().unraw();

View File

@ -46,17 +46,17 @@ impl PyFunctionAttr {
pub fn add_item(&mut self, item: &NestedMeta) -> syn::Result<()> {
match item {
NestedMeta::Meta(syn::Meta::Path(ref ident)) if ident.is_ident("pass_module") => {
NestedMeta::Meta(syn::Meta::Path(ident)) if ident.is_ident("pass_module") => {
self.pass_module = true;
}
NestedMeta::Meta(syn::Meta::Path(ref ident)) => self.add_work(item, ident)?,
NestedMeta::Meta(syn::Meta::NameValue(ref nv)) => {
NestedMeta::Meta(syn::Meta::Path(ident)) => self.add_work(item, ident)?,
NestedMeta::Meta(syn::Meta::NameValue(nv)) => {
self.add_name_value(item, nv)?;
}
NestedMeta::Lit(ref lit) => {
NestedMeta::Lit(lit) => {
self.add_literal(item, lit)?;
}
NestedMeta::Meta(syn::Meta::List(ref list)) => {
NestedMeta::Meta(syn::Meta::List(list)) => {
return Err(syn::Error::new_spanned(
list,
"List is not supported as argument",
@ -68,7 +68,7 @@ impl PyFunctionAttr {
fn add_literal(&mut self, item: &NestedMeta, lit: &syn::Lit) -> syn::Result<()> {
match lit {
syn::Lit::Str(ref lits) if lits.value() == "*" => {
syn::Lit::Str(lits) if lits.value() == "*" => {
// "*"
self.vararg_is_ok(item)?;
self.has_varargs = true;
@ -137,8 +137,8 @@ impl PyFunctionAttr {
}
fn add_name_value(&mut self, item: &NestedMeta, nv: &syn::MetaNameValue) -> syn::Result<()> {
match nv.lit {
syn::Lit::Str(ref litstr) => {
match &nv.lit {
syn::Lit::Str(litstr) => {
if litstr.value() == "*" {
// args="*"
self.vararg_is_ok(item)?;
@ -153,10 +153,10 @@ impl PyFunctionAttr {
self.add_nv_common(item, &nv.path, litstr.value())?;
}
}
syn::Lit::Int(ref litint) => {
syn::Lit::Int(litint) => {
self.add_nv_common(item, &nv.path, format!("{}", litint))?;
}
syn::Lit::Bool(ref litb) => {
syn::Lit::Bool(litb) => {
self.add_nv_common(item, &nv.path, format!("{}", litb.value))?;
}
_ => {
@ -175,32 +175,29 @@ pub fn parse_name_attribute(attrs: &mut Vec<syn::Attribute>) -> syn::Result<Opti
// Using retain will extract all name attributes from the attribute list
attrs.retain(|attr| match attr.parse_meta() {
Ok(syn::Meta::NameValue(ref nv)) if nv.path.is_ident("name") => {
name_attrs.push((nv.lit.clone(), attr.span()));
Ok(syn::Meta::NameValue(nv)) if nv.path.is_ident("name") => {
name_attrs.push((nv.lit, attr.span()));
false
}
_ => true,
});
if 1 < name_attrs.len() {
return Err(syn::Error::new(
name_attrs[0].1,
"#[name] can not be specified multiple times",
));
}
match name_attrs.get(0) {
Some((syn::Lit::Str(s), span)) => {
match name_attrs.as_slice() {
[] => Ok(None),
[(syn::Lit::Str(s), span)] => {
let mut ident: syn::Ident = s.parse()?;
// This span is the whole attribute span, which is nicer for reporting errors.
ident.set_span(*span);
Ok(Some(ident))
}
Some((_, span)) => Err(syn::Error::new(
[(_, span)] => Err(syn::Error::new(
*span,
"Expected string literal for #[name] argument",
)),
None => Ok(None),
[_first_attr, second_attr, ..] => Err(syn::Error::new(
second_attr.1,
"#[name] can not be specified multiple times",
)),
}
}

View File

@ -5,7 +5,7 @@ use proc_macro2::TokenStream;
use quote::quote;
pub fn build_py_methods(ast: &mut syn::ItemImpl) -> syn::Result<TokenStream> {
if let Some((_, ref path, _)) = ast.trait_ {
if let Some((_, path, _)) = &ast.trait_ {
Err(syn::Error::new_spanned(
path,
"#[pymethods] cannot be used on trait impl blocks",

View File

@ -505,11 +505,10 @@ fn impl_arg_param(
// Get Option<&T> from Option<PyRef<T>>
(
quote! { Option<<#tref as pyo3::derive_utils::ExtractExt>::Target> },
// To support Rustc 1.39.0, we don't use as_deref here...
if mut_.is_some() {
quote! { _tmp.as_mut().map(std::ops::DerefMut::deref_mut) }
quote! { _tmp.as_deref_mut() }
} else {
quote! { _tmp.as_ref().map(std::ops::Deref::deref) }
quote! { _tmp.as_deref() }
},
)
} else {
@ -554,7 +553,7 @@ fn impl_arg_param(
fn replace_self(tref: &mut syn::TypeReference, self_path: &syn::Path) {
match &mut *tref.elem {
syn::Type::Reference(tref_inner) => replace_self(tref_inner, self_path),
syn::Type::Path(ref mut tpath) => {
syn::Type::Path(tpath) => {
if let Some(ident) = tpath.path.get_ident() {
if ident == "Self" {
tpath.path = self_path.to_owned();
@ -712,13 +711,8 @@ pub(crate) fn impl_py_getter_def(
/// Split an argument of pyo3::Python from the front of the arg list, if present
fn split_off_python_arg<'a>(args: &'a [FnArg<'a>]) -> (Option<&FnArg>, &[FnArg]) {
if args
.get(0)
.map(|py| utils::is_python(&py.ty))
.unwrap_or(false)
{
(Some(&args[0]), &args[1..])
} else {
(None, args)
match args {
[py, args @ ..] if utils::is_python(&py.ty) => (Some(py), args),
args => (None, args),
}
}

View File

@ -10,8 +10,8 @@ use quote::ToTokens;
use std::collections::HashSet;
pub fn build_py_proto(ast: &mut syn::ItemImpl) -> syn::Result<TokenStream> {
if let Some((_, ref mut path, _)) = ast.trait_ {
let proto = if let Some(ref mut segment) = path.segments.last() {
if let Some((_, path, _)) = &mut ast.trait_ {
let proto = if let Some(segment) = path.segments.last() {
match segment.ident.to_string().as_str() {
"PyObjectProtocol" => &defs::OBJECT,
"PyAsyncProtocol" => &defs::ASYNC,
@ -64,7 +64,7 @@ fn impl_proto_impl(
let mut method_names = HashSet::new();
for iimpl in impls.iter_mut() {
if let syn::ImplItem::Method(ref mut met) = iimpl {
if let syn::ImplItem::Method(met) = iimpl {
// impl Py~Protocol<'p> { type = ... }
if let Some(m) = proto.get_proto(&met.sig.ident) {
impl_method_proto(ty, &mut met.sig, m)?.to_tokens(&mut trait_impls);

View File

@ -10,7 +10,7 @@ pub fn print_err(msg: String, t: TokenStream) {
/// Check if the given type `ty` is `pyo3::Python`.
pub fn is_python(ty: &syn::Type) -> bool {
match ty {
syn::Type::Path(ref typath) => typath
syn::Type::Path(typath) => typath
.path
.segments
.last()
@ -125,9 +125,9 @@ pub fn get_doc(
let mut first = true;
for attr in attrs.iter() {
if let Ok(syn::Meta::NameValue(ref metanv)) = attr.parse_meta() {
if let Ok(syn::Meta::NameValue(metanv)) = attr.parse_meta() {
if metanv.path.is_ident("doc") {
if let syn::Lit::Str(ref litstr) = metanv.lit {
if let syn::Lit::Str(litstr) = metanv.lit {
if first {
first = false;
span = litstr.span();

View File

@ -2,7 +2,6 @@
//! This crate declares only the proc macro attributes, as a crate defining proc macro attributes
//! must not contain any other public items.
extern crate proc_macro;
use proc_macro::TokenStream;
use pyo3_derive_backend::{
build_derive_from_pyobject, build_py_class, build_py_function, build_py_methods,

View File

@ -46,17 +46,12 @@ pub enum ElementType {
impl ElementType {
pub fn from_format(format: &CStr) -> ElementType {
let slice = format.to_bytes();
if slice.len() == 1 {
native_element_type_from_type_char(slice[0])
} else if slice.len() == 2 {
match slice[0] {
b'@' => native_element_type_from_type_char(slice[1]),
b'=' | b'<' | b'>' | b'!' => standard_element_type_from_type_char(slice[1]),
_ => ElementType::Unknown,
match format.to_bytes() {
[char] | [b'@', char] => native_element_type_from_type_char(*char),
[modifier, char] if matches!(modifier, b'=' | b'<' | b'>' | b'!') => {
standard_element_type_from_type_char(*char)
}
} else {
ElementType::Unknown
_ => ElementType::Unknown,
}
}
}

View File

@ -322,7 +322,7 @@ pub unsafe fn PyTZInfo_CheckExact(op: *mut PyObject) -> c_int {
/// Accessor functions
#[cfg(not(PyPy))]
macro_rules! _access_field {
($obj:expr, $type: ident, $field:tt) => {
($obj:expr, $type: ident, $field:ident) => {
(*($obj as *mut $type)).$field
};
}
@ -504,7 +504,7 @@ pub unsafe fn PyDateTime_TIME_GET_TZINFO(o: *mut PyObject) -> *mut PyObject {
// Accessor functions for PyDateTime_Delta
#[cfg(not(PyPy))]
macro_rules! _access_delta_field {
($obj:expr, $field:tt) => {
($obj:expr, $field:ident) => {
_access_field!($obj, PyDateTime_Delta, $field)
};
}

View File

@ -211,7 +211,7 @@ pub mod proc_macro {
#[macro_export]
macro_rules! wrap_pyfunction {
($function_name: ident) => {{
&pyo3::paste::expr! { [<__pyo3_get_function_ $function_name>] }
&pyo3::paste::paste! { [<__pyo3_get_function_ $function_name>] }
}};
($function_name: ident, $arg: expr) => {
@ -244,7 +244,7 @@ macro_rules! wrap_pyfunction {
#[macro_export]
macro_rules! raw_pycfunction {
($function_name: ident) => {{
pyo3::paste::expr! { [<__pyo3_raw_ $function_name>] }
pyo3::paste::paste! { [<__pyo3_raw_ $function_name>] }
}};
}
@ -254,7 +254,7 @@ macro_rules! raw_pycfunction {
#[macro_export]
macro_rules! wrap_pymodule {
($module_name:ident) => {{
pyo3::paste::expr! {
pyo3::paste::paste! {
&|py| unsafe { pyo3::PyObject::from_owned_ptr(py, [<PyInit_ $module_name>]()) }
}
}};
@ -349,9 +349,9 @@ macro_rules! py_run_impl {
#[doc(hidden)]
pub mod doc_test {
macro_rules! doc_comment {
($x:expr, $($tt:tt)*) => {
($x:expr, $module:item) => {
#[doc = $x]
$($tt)*
$module
};
}

View File

@ -317,18 +317,18 @@ fn py_class_method_defs<T: PyMethods>() -> (
let mut new = fallback_new();
for def in T::py_methods() {
match *def {
PyMethodDefType::New(ref def) => {
match def {
PyMethodDefType::New(def) => {
new = def.get_new_func();
debug_assert!(new.is_some());
}
PyMethodDefType::Call(ref def) => {
PyMethodDefType::Call(def) => {
call = def.get_cfunction_with_keywords();
debug_assert!(call.is_some());
}
PyMethodDefType::Method(ref def)
| PyMethodDefType::Class(ref def)
| PyMethodDefType::Static(ref def) => {
PyMethodDefType::Method(def)
| PyMethodDefType::Class(def)
| PyMethodDefType::Static(def) => {
defs.push(def.as_method_def());
}
_ => (),
@ -346,15 +346,15 @@ fn py_class_properties<T: PyClass>() -> Vec<ffi::PyGetSetDef> {
let mut defs = std::collections::HashMap::new();
for def in T::py_methods() {
match *def {
PyMethodDefType::Getter(ref getter) => {
match def {
PyMethodDefType::Getter(getter) => {
if !defs.contains_key(getter.name) {
let _ = defs.insert(getter.name.to_owned(), ffi::PyGetSetDef_INIT);
}
let def = defs.get_mut(getter.name).expect("Failed to call get_mut");
getter.copy_to(def);
}
PyMethodDefType::Setter(ref setter) => {
PyMethodDefType::Setter(setter) => {
if !defs.contains_key(setter.name) {
let _ = defs.insert(setter.name.to_owned(), ffi::PyGetSetDef_INIT);
}

View File

@ -8,18 +8,11 @@ fn test_compile_errors() {
t.compile_fail("tests/ui/invalid_pyclass_args.rs");
t.compile_fail("tests/ui/invalid_pymethod_names.rs");
t.compile_fail("tests/ui/reject_generics.rs");
t.compile_fail("tests/ui/static_ref.rs");
t.compile_fail("tests/ui/wrong_aspyref_lifetimes.rs");
tests_rust_1_43(&t);
tests_rust_1_46(&t);
#[rustversion::since(1.43)]
fn tests_rust_1_43(t: &trybuild::TestCases) {
t.compile_fail("tests/ui/static_ref.rs");
}
#[rustversion::before(1.43)]
fn tests_rust_1_43(_t: &trybuild::TestCases) {}
#[rustversion::since(1.46)]
fn tests_rust_1_46(t: &trybuild::TestCases) {
t.compile_fail("tests/ui/invalid_frompy_derive.rs");

View File

@ -36,7 +36,7 @@ macro_rules! assert_check_exact {
unsafe {
use pyo3::{AsPyPointer, ffi::*};
assert!($check_func(($obj).as_ptr()) != 0);
assert!(pyo3::paste::expr!([<$check_func Exact>])(($obj).as_ptr()) != 0);
assert!(pyo3::paste::paste!([<$check_func Exact>])(($obj).as_ptr()) != 0);
}
};
}
@ -46,7 +46,7 @@ macro_rules! assert_check_only {
unsafe {
use pyo3::{AsPyPointer, ffi::*};
assert!($check_func(($obj).as_ptr()) != 0);
assert!(pyo3::paste::expr!([<$check_func Exact>])(($obj).as_ptr()) == 0);
assert!(pyo3::paste::paste!([<$check_func Exact>])(($obj).as_ptr()) == 0);
}
};
}

View File

@ -196,7 +196,7 @@ impl BaseClassWithDrop {
impl Drop for BaseClassWithDrop {
fn drop(&mut self) {
if let Some(ref mut data) = self.data {
if let Some(data) = &self.data {
data.store(true, Ordering::Relaxed);
}
}
@ -220,7 +220,7 @@ impl SubClassWithDrop {
impl Drop for SubClassWithDrop {
fn drop(&mut self) {
if let Some(ref mut data) = self.data {
if let Some(data) = &self.data {
data.store(true, Ordering::Relaxed);
}
}

View File

@ -59,7 +59,7 @@ impl PySequenceProtocol for ByteSequence {
fn __contains__(&self, other: &PyAny) -> bool {
match u8::extract(other) {
Ok(ref x) => self.elements.contains(x),
Ok(x) => self.elements.contains(&x),
Err(_) => false,
}
}

View File

@ -5,9 +5,9 @@ error: name not allowed with this method type
| ^
error: #[name] can not be specified multiple times
--> $DIR/invalid_pymethod_names.rs:17:5
--> $DIR/invalid_pymethod_names.rs:18:5
|
17 | #[name = "foo"]
18 | #[name = "bar"]
| ^
error: name not allowed with this method type