From 2a630a2a524f6de7ecc48693040701737e33bc64 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sat, 19 Nov 2022 07:33:43 +0100 Subject: [PATCH] Fix being able to call arg-less `#[new]` with any args from Python Fixes #2748 --- newsfragments/2749.fixed.md | 2 ++ pyo3-macros-backend/src/params.rs | 4 ---- tests/test_class_new.rs | 7 +++++++ tests/test_inheritance.rs | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) create mode 100644 newsfragments/2749.fixed.md diff --git a/newsfragments/2749.fixed.md b/newsfragments/2749.fixed.md new file mode 100644 index 00000000..e37742a1 --- /dev/null +++ b/newsfragments/2749.fixed.md @@ -0,0 +1,2 @@ +Fix a bug that allowed `#[new]` pymethods with no arguments to be called from +Python with any argument list. diff --git a/pyo3-macros-backend/src/params.rs b/pyo3-macros-backend/src/params.rs index ab784591..a069d559 100644 --- a/pyo3-macros-backend/src/params.rs +++ b/pyo3-macros-backend/src/params.rs @@ -32,10 +32,6 @@ pub fn impl_arg_params( py: &syn::Ident, fastcall: bool, ) -> Result<(TokenStream, Vec)> { - if spec.signature.arguments.is_empty() { - return Ok((TokenStream::new(), vec![])); - } - let args_array = syn::Ident::new("output", Span::call_site()); if !fastcall && is_forwarded_args(&spec.signature) { diff --git a/tests/test_class_new.rs b/tests/test_class_new.rs index 42755792..b9b0d152 100644 --- a/tests/test_class_new.rs +++ b/tests/test_class_new.rs @@ -2,6 +2,7 @@ use pyo3::exceptions::PyValueError; use pyo3::prelude::*; +use pyo3::types::IntoPyDict; #[pyclass] struct EmptyClassWithNew {} @@ -23,6 +24,12 @@ fn empty_class_with_new() { .unwrap() .downcast::>() .is_ok()); + + // Calling with arbitrary args or kwargs is not ok + assert!(typeobj.call(("some", "args"), None).is_err()); + assert!(typeobj + .call((), Some([("some", "kwarg")].into_py_dict(py))) + .is_err()); }); } diff --git a/tests/test_inheritance.rs b/tests/test_inheritance.rs index be4c75bf..8ef76f87 100644 --- a/tests/test_inheritance.rs +++ b/tests/test_inheritance.rs @@ -259,7 +259,7 @@ mod inheriting_native_type { #[pymethods] impl CustomException { #[new] - fn new() -> Self { + fn new(_exc_arg: &PyAny) -> Self { CustomException { context: "Hello :)", }