diff --git a/pyo3-build-config/src/impl_.rs b/pyo3-build-config/src/impl_.rs index 4fa2a49cb1e..338f82399be 100644 --- a/pyo3-build-config/src/impl_.rs +++ b/pyo3-build-config/src/impl_.rs @@ -1076,7 +1076,8 @@ impl BuildFlags { script.push_str("config = sysconfig.get_config_vars()\n"); for k in &BuildFlags::ALL { - script.push_str(&format!("print(config.get('{}', '0'))\n", k)); + use std::fmt::Write; + writeln!(&mut script, "print(config.get('{}', '0'))", k).unwrap(); } let stdout = run_python_script(interpreter.as_ref(), &script)?; @@ -1225,7 +1226,8 @@ fn find_sysconfigdata(cross: &CrossCompileConfig) -> Result> { sysconfigdata files found:", ); for path in sysconfig_paths { - error_msg += &format!("\n\t{}", path.display()); + use std::fmt::Write; + write!(&mut error_msg, "\n\t{}", path.display()).unwrap(); } bail!("{}\n", error_msg); } diff --git a/src/conversion.rs b/src/conversion.rs index 6dffae77905..14f31d91689 100644 --- a/src/conversion.rs +++ b/src/conversion.rs @@ -521,6 +521,23 @@ where } } +/// ```rust,compile_fail +/// use pyo3::prelude::*; +/// +/// #[pyclass] +/// struct TestClass { +/// num: u32, +/// } +/// +/// let t = TestClass { num: 10 }; +/// +/// Python::with_gil(|py| { +/// let pyvalue = Py::new(py, t).unwrap().to_object(py); +/// let t: TestClass = pyvalue.extract(py).unwrap(); +/// }) +/// ``` +mod test_no_clone {} + #[cfg(test)] mod tests { use crate::types::{IntoPyDict, PyAny, PyDict, PyList}; diff --git a/src/impl_/frompyobject.rs b/src/impl_/frompyobject.rs index 8c0db79833a..1c48e2e4bd9 100644 --- a/src/impl_/frompyobject.rs +++ b/src/impl_/frompyobject.rs @@ -14,13 +14,15 @@ pub fn failed_to_extract_enum( error_names.join(" | ") ); for ((variant_name, error_name), error) in variant_names.iter().zip(error_names).zip(errors) { - err_msg.push('\n'); - err_msg.push_str(&format!( - "- variant {variant_name} ({error_name}): {error_msg}", + use std::fmt::Write; + write!( + &mut err_msg, + "\n- variant {variant_name} ({error_name}): {error_msg}", variant_name = variant_name, error_name = error_name, error_msg = error.value(py).str().unwrap().to_str().unwrap(), - )); + ) + .unwrap(); } PyTypeError::new_err(err_msg) } diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs index 371748db48e..d6206371e3c 100644 --- a/tests/test_compile_error.rs +++ b/tests/test_compile_error.rs @@ -48,6 +48,7 @@ fn _test_compile_errors() { tests_rust_1_57(&t); tests_rust_1_58(&t); tests_rust_1_60(&t); + tests_rust_1_62(&t); #[rustversion::since(1.49)] fn tests_rust_1_49(t: &trybuild::TestCases) { @@ -59,7 +60,7 @@ fn _test_compile_errors() { #[rustversion::since(1.56)] fn tests_rust_1_56(t: &trybuild::TestCases) { t.compile_fail("tests/ui/invalid_closure.rs"); - t.compile_fail("tests/ui/invalid_result_conversion.rs"); + t.compile_fail("tests/ui/pyclass_send.rs"); } @@ -81,7 +82,6 @@ fn _test_compile_errors() { fn tests_rust_1_58(t: &trybuild::TestCases) { t.compile_fail("tests/ui/invalid_pyfunctions.rs"); t.compile_fail("tests/ui/invalid_pymethods.rs"); - t.compile_fail("tests/ui/missing_clone.rs"); t.compile_fail("tests/ui/not_send.rs"); t.compile_fail("tests/ui/not_send2.rs"); t.compile_fail("tests/ui/not_send3.rs"); @@ -99,6 +99,15 @@ fn _test_compile_errors() { #[rustversion::before(1.60)] fn tests_rust_1_60(_t: &trybuild::TestCases) {} + + #[rustversion::since(1.62)] + fn tests_rust_1_62(t: &trybuild::TestCases) { + t.compile_fail("tests/ui/invalid_pymethod_receiver.rs"); + t.compile_fail("tests/ui/invalid_result_conversion.rs"); + } + + #[rustversion::before(1.62)] + fn tests_rust_1_62(_t: &trybuild::TestCases) {} } #[cfg(feature = "nightly")] diff --git a/tests/ui/abi3_nativetype_inheritance.stderr b/tests/ui/abi3_nativetype_inheritance.stderr index 360a0a45bc3..5cf880eb02f 100644 --- a/tests/ui/abi3_nativetype_inheritance.stderr +++ b/tests/ui/abi3_nativetype_inheritance.stderr @@ -4,6 +4,7 @@ error[E0277]: the trait bound `PyDict: PyClass` is not satisfied 5 | #[pyclass(extends=PyDict)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `PyClass` is not implemented for `PyDict` | + = help: the trait `PyClass` is implemented for `TestClass` = note: required because of the requirements on the impl of `PyClassBaseType` for `PyDict` = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -13,7 +14,26 @@ error[E0277]: the trait bound `PyDict: PyClass` is not satisfied 5 | #[pyclass(extends=PyDict)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `PyClass` is not implemented for `PyDict` | + = help: the trait `PyClass` is implemented for `TestClass` = note: required because of the requirements on the impl of `PyClassBaseType` for `PyDict` +<<<<<<< HEAD +======= +note: required by a bound in `PyRefMut` + --> src/pycell.rs + | + | pub struct PyRefMut<'p, T: PyClass> { + | ^^^^^^^^^^^^^^ required by this bound in `PyRefMut` + = note: this error originates in the attribute macro `pyclass` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: the trait bound `PyDict: PyClass` is not satisfied + --> tests/ui/abi3_nativetype_inheritance.rs:5:1 + | +5 | #[pyclass(extends=PyDict)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `PyClass` is not implemented for `PyDict` + | + = help: the trait `PyClass` is implemented for `TestClass` + = note: required because of the requirements on the impl of `PyClassBaseType` for `PyDict` +>>>>>>> 58d4ba833e (Rust 1.62 (#2489)) note: required by a bound in `ThreadCheckerInherited` --> src/impl_/pyclass.rs | diff --git a/tests/ui/invalid_pymethod_receiver.stderr b/tests/ui/invalid_pymethod_receiver.stderr index 9584b37af67..04d2a032b3d 100644 --- a/tests/ui/invalid_pymethod_receiver.stderr +++ b/tests/ui/invalid_pymethod_receiver.stderr @@ -4,11 +4,15 @@ error[E0277]: the trait bound `i32: From<&PyCell>` is not satisfied 8 | fn method_with_invalid_self_type(slf: i32, py: Python<'_>, index: u32) {} | ^^^ the trait `From<&PyCell>` is not implemented for `i32` | - = help: the following implementations were found: - > - > - > - > - and 71 others + = help: the following other types implement trait `From`: + > + > + > + > + > + > + > + > + and 67 others = note: required because of the requirements on the impl of `Into` for `&PyCell` = note: required because of the requirements on the impl of `TryFrom<&PyCell>` for `i32` diff --git a/tests/ui/invalid_result_conversion.stderr b/tests/ui/invalid_result_conversion.stderr index a606f605fcf..31abe95186a 100644 --- a/tests/ui/invalid_result_conversion.stderr +++ b/tests/ui/invalid_result_conversion.stderr @@ -4,8 +4,7 @@ error[E0277]: the trait bound `Result<(), MyError>: IntoPyCallbackOutput<_>` is 21 | #[pyfunction] | ^^^^^^^^^^^^^ the trait `IntoPyCallbackOutput<_>` is not implemented for `Result<(), MyError>` | - = help: the following implementations were found: - as IntoPyCallbackOutput> + = help: the trait `IntoPyCallbackOutput` is implemented for `Result` note: required by a bound in `pyo3::callback::convert` --> src/callback.rs:182:8 | diff --git a/tests/ui/missing_clone.rs b/tests/ui/missing_clone.rs deleted file mode 100644 index d577bdfcdf9..00000000000 --- a/tests/ui/missing_clone.rs +++ /dev/null @@ -1,16 +0,0 @@ -use pyo3::prelude::*; - -#[pyclass] -struct TestClass { - num: u32, -} - -fn main() { - let t = TestClass { num: 10 }; - - let gil = Python::acquire_gil(); - let py = gil.python(); - - let pyvalue = Py::new(py, t).unwrap().to_object(py); - let t: TestClass = pyvalue.extract(py).unwrap(); -} diff --git a/tests/ui/missing_clone.stderr b/tests/ui/missing_clone.stderr deleted file mode 100644 index 59c1f324ff2..00000000000 --- a/tests/ui/missing_clone.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0277]: the trait bound `TestClass: Clone` is not satisfied - --> tests/ui/missing_clone.rs:15:32 - | -15 | let t: TestClass = pyvalue.extract(py).unwrap(); - | ^^^^^^^ the trait `Clone` is not implemented for `TestClass` - | - = note: required because of the requirements on the impl of `pyo3::FromPyObject<'_>` for `TestClass` -note: required by a bound in `pyo3::Py::::extract` - --> src/instance.rs - | - | D: FromPyObject<'p>, - | ^^^^^^^^^^^^^^^^ required by this bound in `pyo3::Py::::extract`