diff --git a/benches/bench_dict.rs b/benches/bench_dict.rs index 2b92159d..64398a65 100644 --- a/benches/bench_dict.rs +++ b/benches/bench_dict.rs @@ -10,7 +10,7 @@ fn iter_dict(b: &mut Bencher<'_>) { let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict(py); let mut sum = 0; b.iter(|| { - for (k, _v) in dict.iter() { + for (k, _v) in dict { let i: u64 = k.extract().unwrap(); sum += i; } diff --git a/benches/bench_list.rs b/benches/bench_list.rs index dd305db7..dd2e3db1 100644 --- a/benches/bench_list.rs +++ b/benches/bench_list.rs @@ -9,7 +9,7 @@ fn iter_list(b: &mut Bencher<'_>) { let list = PyList::new(py, 0..LEN); let mut sum = 0; b.iter(|| { - for x in list.iter() { + for x in list { let i: u64 = x.extract().unwrap(); sum += i; } diff --git a/benches/bench_set.rs b/benches/bench_set.rs index 58abc956..1bc81599 100644 --- a/benches/bench_set.rs +++ b/benches/bench_set.rs @@ -24,7 +24,7 @@ fn iter_set(b: &mut Bencher<'_>) { let set = PySet::new(py, &(0..LEN).collect::>()).unwrap(); let mut sum = 0; b.iter(|| { - for x in set.iter() { + for x in set { let i: u64 = x.extract().unwrap(); sum += i; } diff --git a/benches/bench_tuple.rs b/benches/bench_tuple.rs index 07d7fe2d..e26c1700 100644 --- a/benches/bench_tuple.rs +++ b/benches/bench_tuple.rs @@ -9,7 +9,7 @@ fn iter_tuple(b: &mut Bencher<'_>) { let tuple = PyTuple::new(py, 0..LEN); let mut sum = 0; b.iter(|| { - for x in tuple.iter() { + for x in tuple { let i: u64 = x.extract().unwrap(); sum += i; } diff --git a/pyo3-macros-backend/src/pyimpl.rs b/pyo3-macros-backend/src/pyimpl.rs index 059384e4..2de68f33 100644 --- a/pyo3-macros-backend/src/pyimpl.rs +++ b/pyo3-macros-backend/src/pyimpl.rs @@ -97,7 +97,7 @@ pub fn impl_methods( let mut implemented_proto_fragments = HashSet::new(); - for iimpl in impls.iter_mut() { + for iimpl in impls { match iimpl { syn::ImplItem::Fn(meth) => { let mut fun_options = PyFunctionOptions::from_attrs(&mut meth.attrs)?; diff --git a/pyo3-macros-backend/src/utils.rs b/pyo3-macros-backend/src/utils.rs index c3c4088c..7bb8d240 100644 --- a/pyo3-macros-backend/src/utils.rs +++ b/pyo3-macros-backend/src/utils.rs @@ -79,7 +79,7 @@ pub fn get_doc(attrs: &[syn::Attribute], mut text_signature: Option) -> let mut first = true; let mut current_part = text_signature.unwrap_or_default(); - for attr in attrs.iter() { + for attr in attrs { if attr.path().is_ident("doc") { if let Ok(nv) = attr.meta.require_name_value() { if !first { diff --git a/pytests/src/dict_iter.rs b/pytests/src/dict_iter.rs index 35f3ad8d..5f5992b6 100644 --- a/pytests/src/dict_iter.rs +++ b/pytests/src/dict_iter.rs @@ -22,7 +22,7 @@ impl DictSize { fn iter_dict(&mut self, _py: Python<'_>, dict: &PyDict) -> PyResult { let mut seen = 0u32; - for (sym, values) in dict.iter() { + for (sym, values) in dict { seen += 1; println!( "{:4}/{:4} iterations:{}=>{}", diff --git a/src/conversions/hashbrown.rs b/src/conversions/hashbrown.rs index f8cad574..d80e93d5 100644 --- a/src/conversions/hashbrown.rs +++ b/src/conversions/hashbrown.rs @@ -57,7 +57,7 @@ where fn extract(ob: &'source PyAny) -> Result { let dict: &PyDict = ob.downcast()?; let mut ret = hashbrown::HashMap::with_capacity_and_hasher(dict.len(), S::default()); - for (k, v) in dict.iter() { + for (k, v) in dict { ret.insert(K::extract(k)?, V::extract(v)?); } Ok(ret) diff --git a/src/conversions/indexmap.rs b/src/conversions/indexmap.rs index a83a5612..27324cbb 100644 --- a/src/conversions/indexmap.rs +++ b/src/conversions/indexmap.rs @@ -125,7 +125,7 @@ where fn extract(ob: &'source PyAny) -> Result { let dict: &PyDict = ob.downcast()?; let mut ret = indexmap::IndexMap::with_capacity_and_hasher(dict.len(), S::default()); - for (k, v) in dict.iter() { + for (k, v) in dict { ret.insert(K::extract(k)?, V::extract(v)?); } Ok(ret) diff --git a/src/conversions/std/map.rs b/src/conversions/std/map.rs index f7e9b58c..f79b415b 100644 --- a/src/conversions/std/map.rs +++ b/src/conversions/std/map.rs @@ -74,7 +74,7 @@ where fn extract(ob: &'source PyAny) -> Result { let dict: &PyDict = ob.downcast()?; let mut ret = collections::HashMap::with_capacity_and_hasher(dict.len(), S::default()); - for (k, v) in dict.iter() { + for (k, v) in dict { ret.insert(K::extract(k)?, V::extract(v)?); } Ok(ret) @@ -94,7 +94,7 @@ where fn extract(ob: &'source PyAny) -> Result { let dict: &PyDict = ob.downcast()?; let mut ret = collections::BTreeMap::new(); - for (k, v) in dict.iter() { + for (k, v) in dict { ret.insert(K::extract(k)?, V::extract(v)?); } Ok(ret) diff --git a/src/exceptions.rs b/src/exceptions.rs index a345274c..7618674f 100644 --- a/src/exceptions.rs +++ b/src/exceptions.rs @@ -724,7 +724,7 @@ impl_native_exception!( #[cfg(test)] macro_rules! test_exception { - ($exc_ty:ident $(, $constructor:expr)?) => { + ($exc_ty:ident $(, |$py:tt| $constructor:expr )?) => { #[allow(non_snake_case)] #[test] fn $exc_ty () { @@ -735,7 +735,7 @@ macro_rules! test_exception { let err: $crate::PyErr = { None $( - .or(Some($constructor(py))) + .or(Some({ let $py = py; $constructor })) )? .unwrap_or($exc_ty::new_err("a test exception")) }; @@ -770,12 +770,12 @@ pub mod asyncio { test_exception!(CancelledError); test_exception!(InvalidStateError); test_exception!(TimeoutError); - test_exception!(IncompleteReadError, |_| { - IncompleteReadError::new_err(("partial", "expected")) - }); - test_exception!(LimitOverrunError, |_| { - LimitOverrunError::new_err(("message", "consumed")) - }); + test_exception!(IncompleteReadError, |_| IncompleteReadError::new_err(( + "partial", "expected" + ))); + test_exception!(LimitOverrunError, |_| LimitOverrunError::new_err(( + "message", "consumed" + ))); test_exception!(QueueEmpty); test_exception!(QueueFull); } @@ -1033,9 +1033,10 @@ mod tests { }); } #[cfg(Py_3_11)] - test_exception!(PyBaseExceptionGroup, |_| { - PyBaseExceptionGroup::new_err(("msg", vec![PyValueError::new_err("err")])) - }); + test_exception!(PyBaseExceptionGroup, |_| PyBaseExceptionGroup::new_err(( + "msg", + vec![PyValueError::new_err("err")] + ))); test_exception!(PyBaseException); test_exception!(PyException); test_exception!(PyStopAsyncIteration); @@ -1072,10 +1073,9 @@ mod tests { let err = std::str::from_utf8(invalid_utf8).expect_err("should be invalid utf8"); PyErr::from_value(PyUnicodeDecodeError::new_utf8(py, invalid_utf8, err).unwrap()) }); - test_exception!(PyUnicodeEncodeError, |py: Python<'_>| { - py.eval("chr(40960).encode('ascii')", None, None) - .unwrap_err() - }); + test_exception!(PyUnicodeEncodeError, |py| py + .eval("chr(40960).encode('ascii')", None, None) + .unwrap_err()); test_exception!(PyUnicodeTranslateError, |_| { PyUnicodeTranslateError::new_err(("\u{3042}", 0, 1, "ouch")) }); diff --git a/src/types/dict.rs b/src/types/dict.rs index 4670f522..35796ff7 100644 --- a/src/types/dict.rs +++ b/src/types/dict.rs @@ -654,7 +654,7 @@ mod tests { // Can't just compare against a vector of tuples since we don't have a guaranteed ordering. let mut key_sum = 0; let mut value_sum = 0; - for el in dict.items().iter() { + for el in dict.items() { let tuple = el.downcast::().unwrap(); key_sum += tuple.get_item(0).unwrap().extract::().unwrap(); value_sum += tuple.get_item(1).unwrap().extract::().unwrap(); @@ -675,7 +675,7 @@ mod tests { let dict: &PyDict = ob.downcast(py).unwrap(); // Can't just compare against a vector of tuples since we don't have a guaranteed ordering. let mut key_sum = 0; - for el in dict.keys().iter() { + for el in dict.keys() { key_sum += el.extract::().unwrap(); } assert_eq!(7 + 8 + 9, key_sum); @@ -693,7 +693,7 @@ mod tests { let dict: &PyDict = ob.downcast(py).unwrap(); // Can't just compare against a vector of tuples since we don't have a guaranteed ordering. let mut values_sum = 0; - for el in dict.values().iter() { + for el in dict.values() { values_sum += el.extract::().unwrap(); } assert_eq!(32 + 42 + 123, values_sum); @@ -711,7 +711,7 @@ mod tests { let dict: &PyDict = ob.downcast(py).unwrap(); let mut key_sum = 0; let mut value_sum = 0; - for (key, value) in dict.iter() { + for (key, value) in dict { key_sum += key.extract::().unwrap(); value_sum += value.extract::().unwrap(); } @@ -731,7 +731,7 @@ mod tests { let ob = v.to_object(py); let dict: &PyDict = ob.downcast(py).unwrap(); - for (key, value) in dict.iter() { + for (key, value) in dict { dict.set_item(key, value.extract::().unwrap() + 7) .unwrap(); } diff --git a/src/types/frozenset.rs b/src/types/frozenset.rs index 12bdf1d8..560f762e 100644 --- a/src/types/frozenset.rs +++ b/src/types/frozenset.rs @@ -260,7 +260,7 @@ mod tests { let set = PyFrozenSet::new(py, &[1]).unwrap(); // iter method - for el in set.iter() { + for el in set { assert_eq!(1i32, el.extract::().unwrap()); } diff --git a/src/types/list.rs b/src/types/list.rs index 727e6069..2045d897 100644 --- a/src/types/list.rs +++ b/src/types/list.rs @@ -474,7 +474,7 @@ mod tests { let v = vec![2, 3, 5, 7]; let list = PyList::new(py, &v); let mut idx = 0; - for el in list.iter() { + for el in list { assert_eq!(v[idx], el.extract::().unwrap()); idx += 1; } diff --git a/src/types/sequence.rs b/src/types/sequence.rs index ec4d72f0..e56c7a31 100644 --- a/src/types/sequence.rs +++ b/src/types/sequence.rs @@ -773,7 +773,7 @@ mod tests { let seq = ob.downcast::(py).unwrap(); let repeat_seq = seq.repeat(3).unwrap(); assert_eq!(6, repeat_seq.len().unwrap()); - let repeated = vec!["foo", "bar", "foo", "bar", "foo", "bar"]; + let repeated = ["foo", "bar", "foo", "bar", "foo", "bar"]; for (el, rpt) in repeat_seq.iter().unwrap().zip(repeated.iter()) { assert_eq!(*rpt, el.unwrap().extract::().unwrap()); } diff --git a/src/types/set.rs b/src/types/set.rs index b84ae440..b6176fee 100644 --- a/src/types/set.rs +++ b/src/types/set.rs @@ -368,7 +368,7 @@ mod tests { let set = PySet::new(py, &[1]).unwrap(); // iter method - for el in set.iter() { + for el in set { assert_eq!(1i32, el.extract::<'_, i32>().unwrap()); } diff --git a/src/types/string.rs b/src/types/string.rs index 997d27fb..9c4139b9 100644 --- a/src/types/string.rs +++ b/src/types/string.rs @@ -296,7 +296,7 @@ mod tests { #[test] fn test_to_str_surrogate() { Python::with_gil(|py| { - let obj: PyObject = py.eval(r#"'\ud800'"#, None, None).unwrap().into(); + let obj: PyObject = py.eval(r"'\ud800'", None, None).unwrap().into(); let py_string: &PyString = obj.downcast(py).unwrap(); assert!(py_string.to_str().is_err()); }) @@ -316,7 +316,7 @@ mod tests { fn test_to_string_lossy() { Python::with_gil(|py| { let obj: PyObject = py - .eval(r#"'🐈 Hello \ud800World'"#, None, None) + .eval(r"'🐈 Hello \ud800World'", None, None) .unwrap() .into(); let py_string: &PyString = obj.downcast(py).unwrap(); diff --git a/tests/test_dict_iter.rs b/tests/test_dict_iter.rs index 5d30d4c7..dc32eb61 100644 --- a/tests/test_dict_iter.rs +++ b/tests/test_dict_iter.rs @@ -8,7 +8,7 @@ fn iter_dict_nosegv() { const LEN: usize = 10_000_000; let dict = (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict(py); let mut sum = 0; - for (k, _v) in dict.iter() { + for (k, _v) in dict { let i: u64 = k.extract().unwrap(); sum += i; } diff --git a/tests/ui/invalid_closure.stderr b/tests/ui/invalid_closure.stderr index e4e829d5..90240e5d 100644 --- a/tests/ui/invalid_closure.stderr +++ b/tests/ui/invalid_closure.stderr @@ -1,6 +1,8 @@ error[E0597]: `local_data` does not live long enough --> tests/ui/invalid_closure.rs:7:27 | +6 | let local_data = vec![0, 1, 2, 3, 4]; + | ---------- binding `local_data` declared here 7 | let ref_: &[u8] = &local_data; | ^^^^^^^^^^^ borrowed value does not live long enough ... diff --git a/tests/ui/invalid_frozen_pyclass_borrow.stderr b/tests/ui/invalid_frozen_pyclass_borrow.stderr index e68c2a58..5e09d512 100644 --- a/tests/ui/invalid_frozen_pyclass_borrow.stderr +++ b/tests/ui/invalid_frozen_pyclass_borrow.stderr @@ -25,6 +25,9 @@ error[E0271]: type mismatch resolving `::Frozen == False` note: required by a bound in `pyo3::PyCell::::borrow_mut` --> src/pycell.rs | + | pub fn borrow_mut(&self) -> PyRefMut<'_, T> + | ---------- required by a bound in this associated function + | where | T: PyClass, | ^^^^^^^^^^^^^^ required by this bound in `PyCell::::borrow_mut` @@ -37,6 +40,9 @@ error[E0271]: type mismatch resolving `::Frozen == Fa note: required by a bound in `pyo3::PyCell::::borrow_mut` --> src/pycell.rs | + | pub fn borrow_mut(&self) -> PyRefMut<'_, T> + | ---------- required by a bound in this associated function + | where | T: PyClass, | ^^^^^^^^^^^^^^ required by this bound in `PyCell::::borrow_mut` @@ -49,6 +55,9 @@ error[E0271]: type mismatch resolving `::Frozen == True` note: required by a bound in `pyo3::Py::::get` --> src/instance.rs | + | pub fn get(&self) -> &T + | --- required by a bound in this associated function + | where | T: PyClass + Sync, | ^^^^^^^^^^^^^ required by this bound in `Py::::get` @@ -61,5 +70,8 @@ error[E0271]: type mismatch resolving `::Frozen == True` note: required by a bound in `pyo3::PyCell::::get` --> src/pycell.rs | + | pub fn get(&self) -> &T + | --- required by a bound in this associated function + | where | T: PyClass + Sync, | ^^^^^^^^^^^^^ required by this bound in `PyCell::::get` diff --git a/tests/ui/not_send.stderr b/tests/ui/not_send.stderr index 18547a10..395723cb 100644 --- a/tests/ui/not_send.stderr +++ b/tests/ui/not_send.stderr @@ -7,11 +7,27 @@ error[E0277]: `*mut pyo3::Python<'static>` cannot be shared between threads safe | required by a bound introduced by this call | = help: within `pyo3::Python<'_>`, the trait `Sync` is not implemented for `*mut pyo3::Python<'static>` - = note: required because it appears within the type `PhantomData<*mut Python<'static>>` - = note: required because it appears within the type `NotSend` +note: required because it appears within the type `PhantomData<*mut Python<'static>>` + --> $RUST/core/src/marker.rs + | + | pub struct PhantomData; + | ^^^^^^^^^^^ +note: required because it appears within the type `NotSend` + --> src/impl_/not_send.rs + | + | pub(crate) struct NotSend(PhantomData<*mut Python<'static>>); + | ^^^^^^^ = note: required because it appears within the type `(&GILGuard, NotSend)` - = note: required because it appears within the type `PhantomData<(&GILGuard, NotSend)>` - = note: required because it appears within the type `Python<'_>` +note: required because it appears within the type `PhantomData<(&GILGuard, NotSend)>` + --> $RUST/core/src/marker.rs + | + | pub struct PhantomData; + | ^^^^^^^^^^^ +note: required because it appears within the type `Python<'_>` + --> src/marker.rs + | + | pub struct Python<'py>(PhantomData<(&'py GILGuard, NotSend)>); + | ^^^^^^ = note: required for `&pyo3::Python<'_>` to implement `Send` note: required because it's used within this closure --> tests/ui/not_send.rs:4:22 @@ -22,5 +38,8 @@ note: required because it's used within this closure note: required by a bound in `pyo3::Python::<'py>::allow_threads` --> src/marker.rs | + | pub fn allow_threads(self, f: F) -> T + | ------------- required by a bound in this associated function + | where | F: Ungil + FnOnce() -> T, | ^^^^^ required by this bound in `Python::<'py>::allow_threads` diff --git a/tests/ui/not_send2.stderr b/tests/ui/not_send2.stderr index 8bfa6016..2e6db009 100644 --- a/tests/ui/not_send2.stderr +++ b/tests/ui/not_send2.stderr @@ -10,8 +10,16 @@ error[E0277]: `UnsafeCell` cannot be shared between threads safely | |_________^ `UnsafeCell` cannot be shared between threads safely | = help: within `&PyString`, the trait `Sync` is not implemented for `UnsafeCell` - = note: required because it appears within the type `PyAny` - = note: required because it appears within the type `PyString` +note: required because it appears within the type `PyAny` + --> src/types/any.rs + | + | pub struct PyAny(UnsafeCell); + | ^^^^^ +note: required because it appears within the type `PyString` + --> src/types/string.rs + | + | pub struct PyString(PyAny); + | ^^^^^^^^ = note: required because it appears within the type `&PyString` = note: required for `&&PyString` to implement `Send` note: required because it's used within this closure @@ -23,5 +31,8 @@ note: required because it's used within this closure note: required by a bound in `pyo3::Python::<'py>::allow_threads` --> src/marker.rs | + | pub fn allow_threads(self, f: F) -> T + | ------------- required by a bound in this associated function + | where | F: Ungil + FnOnce() -> T, | ^^^^^ required by this bound in `Python::<'py>::allow_threads`