diff --git a/CHANGELOG.md b/CHANGELOG.md index cfcd85c9..2e179725 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fix undefined symbol for `PyObject_HasAttr` on PyPy. [#2025](https://github.com/PyO3/pyo3/pull/2025) - Fix memory leak in `PyErr::into_value`. [#2026](https://github.com/PyO3/pyo3/pull/2026) +- Fix clippy warning `needless-option-as-deref` in code generated by `#[pyfunction]` and `#[pymethods]`. [#2040](https://github.com/PyO3/pyo3/pull/2040) ## [0.15.1] - 2021-11-19 diff --git a/pyo3-macros-backend/src/params.rs b/pyo3-macros-backend/src/params.rs index 1bbbb472..e781a1d3 100644 --- a/pyo3-macros-backend/src/params.rs +++ b/pyo3-macros-backend/src/params.rs @@ -292,6 +292,7 @@ fn impl_arg_param( Ok(quote_arg_span! { let #mut_ _tmp: #target_ty = #arg_value_or_default; + #[allow(clippy::needless_option_as_deref)] let #arg_name = #borrow_tmp; }) } else { diff --git a/src/buffer.rs b/src/buffer.rs index f155bb11..1f4f57fb 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -163,6 +163,10 @@ fn is_matching_endian(c: u8) -> bool { } /// Trait implemented for possible element types of `PyBuffer`. +/// +/// # Safety +/// +/// This trait must only be implemented for types which represent valid elements of Python buffers. pub unsafe trait Element: Copy { /// Gets whether the element specified in the format string is potentially compatible. /// Alignment and size are checked separately from this function. diff --git a/src/conversion.rs b/src/conversion.rs index e1238edc..ccd690be 100644 --- a/src/conversion.rs +++ b/src/conversion.rs @@ -463,6 +463,10 @@ impl IntoPy> for () { } /// Raw level conversion between `*mut ffi::PyObject` and PyO3 types. +/// +/// # Safety +/// +/// See safety notes on individual functions. pub unsafe trait FromPyPointer<'p>: Sized { /// Convert from an arbitrary `PyObject`. /// diff --git a/src/instance.rs b/src/instance.rs index b8f7ab69..0037abb8 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -17,6 +17,10 @@ use std::ptr::NonNull; /// PyO3 is designed in a way that all references to those types are bound /// to the GIL, which is why you can get a token from all references of those /// types. +/// +/// # Safety +/// +/// This trait must only be implemented for types which cannot be accessed without the GIL. pub unsafe trait PyNativeType: Sized { /// Returns a GIL marker constrained to the lifetime of this type. #[inline] diff --git a/src/type_object.rs b/src/type_object.rs index 0f16f566..bf60d18f 100644 --- a/src/type_object.rs +++ b/src/type_object.rs @@ -16,6 +16,10 @@ use std::thread::{self, ThreadId}; /// is of `PyAny`. /// /// This trait is intended to be used internally. +/// +/// # Safety +/// +/// This trait must only be implemented for types which represent valid layouts of Python objects. pub unsafe trait PyLayout {} /// `T: PySizedLayout` represents that `T` is not a instance of @@ -31,6 +35,11 @@ pub trait PySizedLayout: PyLayout + Sized {} /// - the return value of type_object must always point to the same PyTypeObject instance /// /// It is safely implemented by the `pyclass` macro. +/// +/// # Safety +/// +/// Implementations must provide an implementation for `type_object_raw` which infallibly produces a +/// non-null pointer to the corresponding Python type object. pub unsafe trait PyTypeInfo: Sized { /// Class name. const NAME: &'static str; @@ -57,6 +66,8 @@ pub unsafe trait PyTypeInfo: Sized { /// Python object types that have a corresponding type object. /// +/// # Safety +/// /// This trait is marked unsafe because not fulfilling the contract for type_object /// leads to UB. /// diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs index 9631b2a1..19072289 100644 --- a/tests/test_compile_error.rs +++ b/tests/test_compile_error.rs @@ -25,15 +25,13 @@ fn _test_compile_errors() { 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"); - t.compile_fail("tests/ui/wrong_aspyref_lifetimes.rs"); tests_rust_1_49(&t); - tests_rust_1_54(&t); tests_rust_1_55(&t); tests_rust_1_56(&t); + tests_rust_1_57(&t); #[rustversion::since(1.49)] fn tests_rust_1_49(t: &trybuild::TestCases) { @@ -42,14 +40,6 @@ fn _test_compile_errors() { #[rustversion::before(1.49)] fn tests_rust_1_49(_t: &trybuild::TestCases) {} - #[rustversion::since(1.54)] - fn tests_rust_1_54(t: &trybuild::TestCases) { - t.compile_fail("tests/ui/invalid_frompy_derive.rs"); - t.compile_fail("tests/ui/static_ref.rs"); - } - #[rustversion::before(1.54)] - fn tests_rust_1_54(_t: &trybuild::TestCases) {} - #[rustversion::since(1.55)] fn tests_rust_1_55(t: &trybuild::TestCases) { t.compile_fail("tests/ui/invalid_pymethod_receiver.rs"); @@ -70,4 +60,15 @@ fn _test_compile_errors() { #[rustversion::before(1.56)] fn tests_rust_1_56(_t: &trybuild::TestCases) {} + + #[rustversion::since(1.57)] + fn tests_rust_1_57(t: &trybuild::TestCases) { + t.compile_fail("tests/ui/invalid_argument_attributes.rs"); + t.compile_fail("tests/ui/invalid_frompy_derive.rs"); + t.compile_fail("tests/ui/static_ref.rs"); + t.compile_fail("tests/ui/wrong_aspyref_lifetimes.rs"); + } + + #[rustversion::before(1.57)] + fn tests_rust_1_57(_t: &trybuild::TestCases) {} } diff --git a/tests/ui/invalid_argument_attributes.stderr b/tests/ui/invalid_argument_attributes.stderr index dd830a3e..ed6479d5 100644 --- a/tests/ui/invalid_argument_attributes.stderr +++ b/tests/ui/invalid_argument_attributes.stderr @@ -5,10 +5,10 @@ error: expected `from_py_with` | ^^^ error: expected `=` - --> tests/ui/invalid_argument_attributes.rs:7:32 + --> tests/ui/invalid_argument_attributes.rs:7:45 | 7 | fn from_py_with_no_value(#[pyo3(from_py_with)] param: String) {} - | ^^^^^^^^^^^^^^ + | ^ error: expected `from_py_with` --> tests/ui/invalid_argument_attributes.rs:10:31 diff --git a/tests/ui/invalid_frompy_derive.stderr b/tests/ui/invalid_frompy_derive.stderr index b5cb180d..d16c082f 100644 --- a/tests/ui/invalid_frompy_derive.stderr +++ b/tests/ui/invalid_frompy_derive.stderr @@ -109,10 +109,10 @@ error: attribute name cannot be empty | ^^ error: unexpected end of input, expected string literal - --> tests/ui/invalid_frompy_derive.rs:100:21 + --> tests/ui/invalid_frompy_derive.rs:100:22 | 100 | #[pyo3(attribute())] - | ^^ + | ^ error: expected at most one argument: `item` or `item(key)` --> tests/ui/invalid_frompy_derive.rs:106:20 @@ -121,10 +121,10 @@ error: expected at most one argument: `item` or `item(key)` | ^ error: unexpected end of input, expected literal - --> tests/ui/invalid_frompy_derive.rs:112:16 + --> tests/ui/invalid_frompy_derive.rs:112:17 | 112 | #[pyo3(item())] - | ^^ + | ^ error: only one of `attribute` or `item` can be provided --> tests/ui/invalid_frompy_derive.rs:118:5 @@ -171,10 +171,10 @@ error: cannot derive FromPyObject for empty structs and variants = note: this error originates in the derive macro `FromPyObject` (in Nightly builds, run with -Z macro-backtrace for more info) error: expected `=` - --> tests/ui/invalid_frompy_derive.rs:158:11 + --> tests/ui/invalid_frompy_derive.rs:158:24 | 158 | #[pyo3(from_py_with)] - | ^^^^^^^^^^^^^^ + | ^ error: expected string literal --> tests/ui/invalid_frompy_derive.rs:164:27 diff --git a/tests/ui/static_ref.stderr b/tests/ui/static_ref.stderr index 58fc6a53..9165f63a 100644 --- a/tests/ui/static_ref.stderr +++ b/tests/ui/static_ref.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'py` 4 | #[pyfunction] | ^^^^^^^^^^^^^ | -note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the body at 4:1... +note: first, the lifetime cannot outlive the anonymous lifetime #1 defined here... --> tests/ui/static_ref.rs:4:1 | 4 | #[pyfunction] diff --git a/tests/ui/wrong_aspyref_lifetimes.stderr b/tests/ui/wrong_aspyref_lifetimes.stderr index 319f4ee5..0042bc6b 100644 --- a/tests/ui/wrong_aspyref_lifetimes.stderr +++ b/tests/ui/wrong_aspyref_lifetimes.stderr @@ -2,9 +2,9 @@ error[E0505]: cannot move out of `gil` because it is borrowed --> tests/ui/wrong_aspyref_lifetimes.rs:7:10 | 6 | let dict: &PyDict = dict.as_ref(gil.python()); - | --- borrow of `gil` occurs here + | ------------ borrow of `gil` occurs here 7 | drop(gil); | ^^^ move out of `gil` occurs here 8 | 9 | let _py: Python = dict.py(); // Obtain a Python<'p> without GIL. - | ---- borrow later used here + | --------- borrow later used here