From a840ebbb5a82bde33fa1b0c1de1d059c6530bde5 Mon Sep 17 00:00:00 2001 From: kngwyu Date: Thu, 18 Jun 2020 18:49:43 +0900 Subject: [PATCH] Support Rust 1.39.0 --- .travis.yml | 3 +++ Cargo.toml | 1 + README.md | 3 ++- build.rs | 6 +++--- pyo3-derive-backend/src/pyfunction.rs | 19 ++++++++++-------- pyo3-derive-backend/src/pymethod.rs | 16 ++++++++------- tests/test_compile_error.rs | 28 ++++++++++++++++++--------- 7 files changed, 48 insertions(+), 28 deletions(-) diff --git a/.travis.yml b/.travis.yml index b1f946d8bbe..06b7f48a7ec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,6 +23,9 @@ jobs: - name: Nightly python: "3.7" env: TRAVIS_RUST_VERSION=nightly FEATURES="nightly" + - name: Minimum Stable + python: "3.7" + env: TRAVIS_RUST_VERSION=1.39.0 - name: PyPy3.5 7.0 # Tested via anaconda PyPy (since travis's PyPy version is too old) python: "3.7" env: FEATURES="pypy" PATH="$PATH:/opt/anaconda/envs/pypy3/bin" diff --git a/Cargo.toml b/Cargo.toml index 35fa56cdda6..52980a97331 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,6 +33,7 @@ unindent = { version = "0.1.4", optional = true } [dev-dependencies] assert_approx_eq = "1.1.0" trybuild = "1.0.23" +rustversion = "1.0" [features] default = ["macros"] diff --git a/README.md b/README.md index 305b02f8d1d..faba2e50d8c 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,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.42](https://img.shields.io/badge/rustc-1.39+-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. @@ -16,7 +17,7 @@ A comparison with rust-cpython can be found [in the guide](https://pyo3.rs/maste ## Usage -PyO3 supports Python 3.5 and up. The minimum required Rust version is 1.44. +PyO3 supports Python 3.5 and up. The minimum required Rust version is 1.39.0. PyPy is also supported (via cpyext) for Python 3.5 only, targeted PyPy version is 7.0.0. Please refer to the [pypy section in the guide](https://pyo3.rs/master/pypy.html). diff --git a/build.rs b/build.rs index 15621c35042..a091e3e3169 100644 --- a/build.rs +++ b/build.rs @@ -69,8 +69,8 @@ impl FromStr for PythonInterpreterKind { type Err = Box; fn from_str(s: &str) -> Result { match s { - "CPython" => Ok(Self::CPython), - "PyPy" => Ok(Self::PyPy), + "CPython" => Ok(PythonInterpreterKind::CPython), + "PyPy" => Ok(PythonInterpreterKind::PyPy), _ => Err(format!("Invalid interpreter: {}", s).into()), } } @@ -295,7 +295,7 @@ fn run_python_script(interpreter: &Path, script: &str) -> Result { ); } } - Ok(ok) if !ok.status.success() => bail!("Python script failed: {}"), + Ok(ref ok) if !ok.status.success() => bail!("Python script failed: {}"), Ok(ok) => Ok(String::from_utf8(ok.stdout)?), } } diff --git a/pyo3-derive-backend/src/pyfunction.rs b/pyo3-derive-backend/src/pyfunction.rs index 689cd45f516..96ef584a9ca 100644 --- a/pyo3-derive-backend/src/pyfunction.rs +++ b/pyo3-derive-backend/src/pyfunction.rs @@ -179,22 +179,25 @@ pub fn parse_name_attribute(attrs: &mut Vec) -> syn::Result true, }); - match &*name_attrs { - [] => Ok(None), - [(syn::Lit::Str(s), span)] => { + 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)) => { 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)) } - [(_, span)] => Err(syn::Error::new( + Some((_, span)) => Err(syn::Error::new( *span, "Expected string literal for #[name] argument", )), - [(_, span), ..] => Err(syn::Error::new( - *span, - "#[name] can not be specified multiple times", - )), + None => Ok(None), } } diff --git a/pyo3-derive-backend/src/pymethod.rs b/pyo3-derive-backend/src/pymethod.rs index d1f35df0241..a4ef8c497ac 100644 --- a/pyo3-derive-backend/src/pymethod.rs +++ b/pyo3-derive-backend/src/pymethod.rs @@ -512,10 +512,11 @@ fn impl_arg_param( }; if let syn::Type::Reference(tref) = ty { let (tref, mut_) = tref_preprocess(tref); - let as_deref = if mut_.is_some() { - quote! { as_deref_mut } + // To support Rustc 1.39.0, we don't use as_deref here... + let tmp_as_deref = if mut_.is_some() { + quote! { _tmp.as_mut().map(std::ops::DerefMut::deref_mut) } } else { - quote! { as_deref } + quote! { _tmp.as_ref().map(std::ops::Deref::deref) } }; // Get Option<&T> from Option> quote! { @@ -525,7 +526,7 @@ fn impl_arg_param( }, None => #default, }; - let #arg_name = _tmp.#as_deref(); + let #arg_name = #tmp_as_deref; } } else { quote! { @@ -731,8 +732,9 @@ 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]) { - match args { - [py, rest @ ..] if utils::if_type_is_python(&py.ty) => (Some(py), rest), - rest => (None, rest), + if args.get(0).map(|py| utils::if_type_is_python(&py.ty)) == Some(true) { + (Some(&args[0]), &args[1..]) + } else { + (None, args) } } diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs index 67ab76980b4..468fac9037d 100644 --- a/tests/test_compile_error.rs +++ b/tests/test_compile_error.rs @@ -1,13 +1,23 @@ #[test] fn test_compile_errors() { let t = trybuild::TestCases::new(); - t.compile_fail("tests/ui/invalid_macro_args.rs"); - t.compile_fail("tests/ui/invalid_property_args.rs"); - t.compile_fail("tests/ui/invalid_pyclass_args.rs"); - t.compile_fail("tests/ui/missing_clone.rs"); - t.compile_fail("tests/ui/reject_generics.rs"); - t.compile_fail("tests/ui/wrong_aspyref_lifetimes.rs"); - t.compile_fail("tests/ui/static_ref.rs"); - #[cfg(not(feature = "nightly"))] - t.compile_fail("tests/ui/invalid_pymethod_names.rs"); + testcase_common(&t); + testcase_latest_stable(&t); + + fn testcase_common(t: &trybuild::TestCases) { + t.compile_fail("tests/ui/invalid_macro_args.rs"); + t.compile_fail("tests/ui/invalid_property_args.rs"); + t.compile_fail("tests/ui/invalid_pyclass_args.rs"); + t.compile_fail("tests/ui/missing_clone.rs"); + t.compile_fail("tests/ui/reject_generics.rs"); + t.compile_fail("tests/ui/wrong_aspyref_lifetimes.rs"); + t.compile_fail("tests/ui/invalid_pymethod_names.rs"); + } + + #[rustversion::all(since(1.43))] + fn testcase_latest_stable(t: &trybuild::TestCases) { + t.compile_fail("tests/ui/static_ref.rs"); + } + #[rustversion::before(1.43)] + fn testcase_latest_stable(_t: &trybuild::TestCases) {} }