Support Rust 1.39.0

This commit is contained in:
kngwyu 2020-06-18 18:49:43 +09:00
parent 64408142f5
commit a840ebbb5a
7 changed files with 48 additions and 28 deletions

View File

@ -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"

View File

@ -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"]

View File

@ -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).

View File

@ -69,8 +69,8 @@ impl FromStr for PythonInterpreterKind {
type Err = Box<dyn std::error::Error>;
fn from_str(s: &str) -> Result<Self> {
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<String> {
);
}
}
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)?),
}
}

View File

@ -179,22 +179,25 @@ pub fn parse_name_attribute(attrs: &mut Vec<syn::Attribute>) -> syn::Result<Opti
_ => 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),
}
}

View File

@ -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<PyRef<T>>
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)
}
}

View File

@ -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) {}
}