From d32ef64050545478581d0513ea36cb2824c55625 Mon Sep 17 00:00:00 2001 From: Nick Drozd Date: Fri, 19 Apr 2024 16:01:12 -0400 Subject: [PATCH 1/7] Enable lint: inefficient_to_string --- src/lib.rs | 1 + src/panic.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index b400f143f5a..974883618ee 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,6 +19,7 @@ non_local_definitions, ) )))] +#![deny(clippy::inefficient_to_string)] //! Rust bindings to the Python interpreter. //! diff --git a/src/panic.rs b/src/panic.rs index 50489d50aeb..02fcbfd1f90 100644 --- a/src/panic.rs +++ b/src/panic.rs @@ -23,7 +23,7 @@ impl PanicException { pub(crate) fn from_panic_payload(payload: Box) -> PyErr { if let Some(string) = payload.downcast_ref::() { Self::new_err((string.clone(),)) - } else if let Some(s) = payload.downcast_ref::<&str>() { + } else if let Ok(s) = payload.downcast::<&str>() { Self::new_err((s.to_string(),)) } else { Self::new_err(("panic from Rust code",)) From 7d7c4a74c5876a6332441bd2a97401bcef04b93b Mon Sep 17 00:00:00 2001 From: Nick Drozd Date: Sun, 21 Apr 2024 11:59:40 -0400 Subject: [PATCH 2/7] Enable lint: type_repetition_in_bounds --- src/impl_/extract_argument.rs | 10 ++-------- src/lib.rs | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/impl_/extract_argument.rs b/src/impl_/extract_argument.rs index 485b8645086..296b29ad9d7 100644 --- a/src/impl_/extract_argument.rs +++ b/src/impl_/extract_argument.rs @@ -37,10 +37,7 @@ where } } -impl<'a, 'py, T: 'py> PyFunctionArgument<'a, 'py> for &'a Bound<'py, T> -where - T: PyTypeCheck, -{ +impl<'a, 'py, T: 'py + PyTypeCheck> PyFunctionArgument<'a, 'py> for &'a Bound<'py, T> { type Holder = Option<()>; #[inline] @@ -49,10 +46,7 @@ where } } -impl<'a, 'py, T: 'py> PyFunctionArgument<'a, 'py> for Option<&'a Bound<'py, T>> -where - T: PyTypeCheck, -{ +impl<'a, 'py, T: 'py + PyTypeCheck> PyFunctionArgument<'a, 'py> for Option<&'a Bound<'py, T>> { type Holder = (); #[inline] diff --git a/src/lib.rs b/src/lib.rs index 974883618ee..86ac3ef2f63 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,7 +19,7 @@ non_local_definitions, ) )))] -#![deny(clippy::inefficient_to_string)] +#![deny(clippy::inefficient_to_string, clippy::type_repetition_in_bounds)] //! Rust bindings to the Python interpreter. //! From 96026dd6cde3f4592bfc3f033bda095cbf4f6a7a Mon Sep 17 00:00:00 2001 From: Nick Drozd Date: Sun, 21 Apr 2024 12:04:15 -0400 Subject: [PATCH 3/7] Enable lint: map_unwrap_or --- src/conversions/chrono.rs | 6 +++--- src/err/mod.rs | 15 ++++++++------- src/lib.rs | 6 +++++- src/marker.rs | 6 ++---- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/conversions/chrono.rs b/src/conversions/chrono.rs index 544d1cf2663..016c842f6a5 100644 --- a/src/conversions/chrono.rs +++ b/src/conversions/chrono.rs @@ -1194,7 +1194,7 @@ mod tests { let py_time = CatchWarnings::enter(py, |_| Ok(time.to_object(py))).unwrap(); let roundtripped: NaiveTime = py_time.extract(py).expect("Round trip"); // Leap seconds are not roundtripped - let expected_roundtrip_time = micro.checked_sub(1_000_000).map(|micro| NaiveTime::from_hms_micro_opt(hour, min, sec, micro).unwrap()).unwrap_or(time); + let expected_roundtrip_time = micro.checked_sub(1_000_000).map_or(time, |micro| NaiveTime::from_hms_micro_opt(hour, min, sec, micro).unwrap()); assert_eq!(expected_roundtrip_time, roundtripped); } }) @@ -1241,7 +1241,7 @@ mod tests { let py_dt = CatchWarnings::enter(py, |_| Ok(dt.into_py(py))).unwrap(); let roundtripped: DateTime = py_dt.extract(py).expect("Round trip"); // Leap seconds are not roundtripped - let expected_roundtrip_time = micro.checked_sub(1_000_000).map(|micro| NaiveTime::from_hms_micro_opt(hour, min, sec, micro).unwrap()).unwrap_or(time); + let expected_roundtrip_time = micro.checked_sub(1_000_000).map_or(time, |micro| NaiveTime::from_hms_micro_opt(hour, min, sec, micro).unwrap()); let expected_roundtrip_dt: DateTime = NaiveDateTime::new(date, expected_roundtrip_time).and_utc(); assert_eq!(expected_roundtrip_dt, roundtripped); } @@ -1269,7 +1269,7 @@ mod tests { let py_dt = CatchWarnings::enter(py, |_| Ok(dt.into_py(py))).unwrap(); let roundtripped: DateTime = py_dt.extract(py).expect("Round trip"); // Leap seconds are not roundtripped - let expected_roundtrip_time = micro.checked_sub(1_000_000).map(|micro| NaiveTime::from_hms_micro_opt(hour, min, sec, micro).unwrap()).unwrap_or(time); + let expected_roundtrip_time = micro.checked_sub(1_000_000).map_or(time, |micro| NaiveTime::from_hms_micro_opt(hour, min, sec, micro).unwrap()); let expected_roundtrip_dt: DateTime = NaiveDateTime::new(date, expected_roundtrip_time).and_local_timezone(offset).unwrap(); assert_eq!(expected_roundtrip_dt, roundtripped); } diff --git a/src/err/mod.rs b/src/err/mod.rs index d923761af1d..e304c2a8a8b 100644 --- a/src/err/mod.rs +++ b/src/err/mod.rs @@ -428,9 +428,10 @@ impl PyErr { let msg = pvalue .as_ref() .and_then(|obj| obj.bind(py).str().ok()) - .map(|py_str| py_str.to_string_lossy().into()) - .unwrap_or_else(|| String::from("Unwrapped panic from Python code")); - + .map_or_else( + || String::from("Unwrapped panic from Python code"), + |py_str| py_str.to_string_lossy().into(), + ); let state = PyErrState::FfiTuple { ptype, pvalue, @@ -451,10 +452,10 @@ impl PyErr { let state = PyErrStateNormalized::take(py)?; let pvalue = state.pvalue.bind(py); if pvalue.get_type().as_ptr() == PanicException::type_object_raw(py).cast() { - let msg: String = pvalue - .str() - .map(|py_str| py_str.to_string_lossy().into()) - .unwrap_or_else(|_| String::from("Unwrapped panic from Python code")); + let msg: String = pvalue.str().map_or_else( + |_| String::from("Unwrapped panic from Python code"), + |py_str| py_str.to_string_lossy().into(), + ); Self::print_panic_and_unwind(py, PyErrState::Normalized(state), msg) } diff --git a/src/lib.rs b/src/lib.rs index 86ac3ef2f63..9aa24d21193 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,7 +19,11 @@ non_local_definitions, ) )))] -#![deny(clippy::inefficient_to_string, clippy::type_repetition_in_bounds)] +#![deny( + clippy::inefficient_to_string, + clippy::map_unwrap_or, + clippy::type_repetition_in_bounds +)] //! Rust bindings to the Python interpreter. //! diff --git a/src/marker.rs b/src/marker.rs index 29aae69d4f2..2b4d0f4213b 100644 --- a/src/marker.rs +++ b/src/marker.rs @@ -688,10 +688,8 @@ impl<'py> Python<'py> { return Err(PyErr::fetch(self)); } - let globals = globals - .map(|dict| dict.as_ptr()) - .unwrap_or_else(|| ffi::PyModule_GetDict(mptr)); - let locals = locals.map(|dict| dict.as_ptr()).unwrap_or(globals); + let globals = globals.map_or_else(|| ffi::PyModule_GetDict(mptr), |dict| dict.as_ptr()); + let locals = locals.map_or(globals, |dict| dict.as_ptr()); // If `globals` don't provide `__builtins__`, most of the code will fail if Python // version is <3.10. That's probably not what user intended, so insert `__builtins__` From 80782ca26cbb9e95e06f3ba1f3ab1640447af7e6 Mon Sep 17 00:00:00 2001 From: Nick Drozd Date: Tue, 23 Apr 2024 16:53:32 -0400 Subject: [PATCH 4/7] Enable lint: implicit_clone --- src/lib.rs | 1 + src/pybacked.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 9aa24d21193..b121f075eb5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,6 +20,7 @@ ) )))] #![deny( + clippy::implicit_clone, clippy::inefficient_to_string, clippy::map_unwrap_or, clippy::type_repetition_in_bounds diff --git a/src/pybacked.rs b/src/pybacked.rs index e0bacb86144..078fa1744e9 100644 --- a/src/pybacked.rs +++ b/src/pybacked.rs @@ -152,7 +152,7 @@ impl From> for PyBackedBytes { let b = py_bytes.as_bytes(); let data = NonNull::from(b); Self { - storage: PyBackedBytesStorage::Python(py_bytes.to_owned().unbind()), + storage: PyBackedBytesStorage::Python(py_bytes.clone().unbind()), data, } } From cab28df706c57a1f21174ab2a3f6a2be96eb9748 Mon Sep 17 00:00:00 2001 From: Nick Drozd Date: Wed, 24 Apr 2024 00:38:44 -0400 Subject: [PATCH 5/7] Enable lint: ignored_unit_patterns --- src/impl_/extract_argument.rs | 4 ++-- src/lib.rs | 1 + src/pycell.rs | 8 ++++---- src/types/bytearray.rs | 2 +- src/types/bytes.rs | 2 +- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/impl_/extract_argument.rs b/src/impl_/extract_argument.rs index 296b29ad9d7..5a10691c63b 100644 --- a/src/impl_/extract_argument.rs +++ b/src/impl_/extract_argument.rs @@ -32,7 +32,7 @@ where type Holder = (); #[inline] - fn extract(obj: &'a Bound<'py, PyAny>, _: &'a mut ()) -> PyResult { + fn extract(obj: &'a Bound<'py, PyAny>, (): &'a mut ()) -> PyResult { obj.extract() } } @@ -50,7 +50,7 @@ impl<'a, 'py, T: 'py + PyTypeCheck> PyFunctionArgument<'a, 'py> for Option<&'a B type Holder = (); #[inline] - fn extract(obj: &'a Bound<'py, PyAny>, _: &'a mut ()) -> PyResult { + fn extract(obj: &'a Bound<'py, PyAny>, (): &'a mut ()) -> PyResult { if obj.is_none() { Ok(None) } else { diff --git a/src/lib.rs b/src/lib.rs index b121f075eb5..3fa34665fc7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,6 +20,7 @@ ) )))] #![deny( + clippy::ignored_unit_patterns, clippy::implicit_clone, clippy::inefficient_to_string, clippy::map_unwrap_or, diff --git a/src/pycell.rs b/src/pycell.rs index 80ccff0a030..820964112e9 100644 --- a/src/pycell.rs +++ b/src/pycell.rs @@ -404,7 +404,7 @@ impl PyCell { self.0 .borrow_checker() .try_borrow_unguarded() - .map(|_: ()| &*self.0.get_ptr()) + .map(|()| &*self.0.get_ptr()) } /// Provide an immutable borrow of the value `T` without acquiring the GIL. @@ -662,7 +662,7 @@ impl<'py, T: PyClass> PyRef<'py, T> { cell.ensure_threadsafe(); cell.borrow_checker() .try_borrow() - .map(|_| Self { inner: obj.clone() }) + .map(|()| Self { inner: obj.clone() }) } pub(crate) fn try_borrow_threadsafe(obj: &Bound<'py, T>) -> Result { @@ -670,7 +670,7 @@ impl<'py, T: PyClass> PyRef<'py, T> { cell.check_threadsafe()?; cell.borrow_checker() .try_borrow() - .map(|_| Self { inner: obj.clone() }) + .map(|()| Self { inner: obj.clone() }) } } @@ -859,7 +859,7 @@ impl<'py, T: PyClass> PyRefMut<'py, T> { cell.ensure_threadsafe(); cell.borrow_checker() .try_borrow_mut() - .map(|_| Self { inner: obj.clone() }) + .map(|()| Self { inner: obj.clone() }) } } diff --git a/src/types/bytearray.rs b/src/types/bytearray.rs index 8bc4bf55d5b..6bee5ee2a84 100644 --- a/src/types/bytearray.rs +++ b/src/types/bytearray.rs @@ -95,7 +95,7 @@ impl PyByteArray { std::ptr::write_bytes(buffer, 0u8, len); // (Further) Initialise the bytearray in init // If init returns an Err, pypybytearray will automatically deallocate the buffer - init(std::slice::from_raw_parts_mut(buffer, len)).map(|_| pybytearray) + init(std::slice::from_raw_parts_mut(buffer, len)).map(|()| pybytearray) } } diff --git a/src/types/bytes.rs b/src/types/bytes.rs index f3da65c7c97..cecdfdf2dd8 100644 --- a/src/types/bytes.rs +++ b/src/types/bytes.rs @@ -91,7 +91,7 @@ impl PyBytes { std::ptr::write_bytes(buffer, 0u8, len); // (Further) Initialise the bytestring in init // If init returns an Err, pypybytearray will automatically deallocate the buffer - init(std::slice::from_raw_parts_mut(buffer, len)).map(|_| pybytes) + init(std::slice::from_raw_parts_mut(buffer, len)).map(|()| pybytes) } } From 9d8cc59d8f88e818692b0fd97fcc6938454457cd Mon Sep 17 00:00:00 2001 From: Nick Drozd Date: Wed, 24 Apr 2024 20:23:35 -0400 Subject: [PATCH 6/7] Enable lint: redundant_else --- src/lib.rs | 1 + src/types/tuple.rs | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 3fa34665fc7..cf2f0ab8b3b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,6 +24,7 @@ clippy::implicit_clone, clippy::inefficient_to_string, clippy::map_unwrap_or, + clippy::redundant_else, clippy::type_repetition_in_bounds )] diff --git a/src/types/tuple.rs b/src/types/tuple.rs index 563a81983fa..b56307ef4e6 100644 --- a/src/types/tuple.rs +++ b/src/types/tuple.rs @@ -691,14 +691,14 @@ fn type_output() -> TypeInfo { fn extract_bound(obj: &Bound<'py, PyAny>) -> PyResult { let t = obj.downcast::()?; - if t.len() == $length { + if t.len() != $length { + Err(wrong_tuple_length(t, $length)) + } else { #[cfg(any(Py_LIMITED_API, PyPy, GraalPy))] return Ok(($(t.get_borrowed_item($n)?.extract::<$T>()?,)+)); #[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))] unsafe {return Ok(($(t.get_borrowed_item_unchecked($n).extract::<$T>()?,)+));} - } else { - Err(wrong_tuple_length(t, $length)) } } From ee0a9ad2aa2f56ec823422fadc4eb6cb3c16299b Mon Sep 17 00:00:00 2001 From: Nick Drozd Date: Wed, 24 Apr 2024 20:46:37 -0400 Subject: [PATCH 7/7] Enable clippy for pyo3-macros --- pyo3-macros/src/lib.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pyo3-macros/src/lib.rs b/pyo3-macros/src/lib.rs index 64756a1c73b..19488ab7293 100644 --- a/pyo3-macros/src/lib.rs +++ b/pyo3-macros/src/lib.rs @@ -1,6 +1,7 @@ //! This crate declares only the proc macro attributes, as a crate defining proc macro attributes //! must not contain any other public items. +#![deny(clippy::all, clippy::pedantic, clippy::nursery)] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] use proc_macro::TokenStream; use proc_macro2::TokenStream as TokenStream2; @@ -204,7 +205,7 @@ fn pymethods_impl( .into() } -fn methods_type() -> PyClassMethodsType { +const fn methods_type() -> PyClassMethodsType { if cfg!(feature = "multiple-pymethods") { PyClassMethodsType::Inventory } else { @@ -218,6 +219,6 @@ trait UnwrapOrCompileError { impl UnwrapOrCompileError for syn::Result { fn unwrap_or_compile_error(self) -> TokenStream2 { - self.unwrap_or_else(|e| e.into_compile_error()) + self.unwrap_or_else(syn::Error::into_compile_error) } }