diff --git a/pytests/src/pyfunctions.rs b/pytests/src/pyfunctions.rs index 8d3da83cee3..ce7494f7c5f 100644 --- a/pytests/src/pyfunctions.rs +++ b/pytests/src/pyfunctions.rs @@ -87,11 +87,57 @@ fn with_custom_type_annotations<'py>( a } +#[allow(clippy::too_many_arguments)] +#[pyfunction( + signature = ( + *, + ant = None, + bear = None, + cat = None, + dog = None, + elephant = None, + fox = None, + goat = None, + horse = None, + iguana = None, + jaguar = None, + koala = None, + lion = None, + monkey = None, + newt = None, + owl = None, + penguin = None + ) +)] +fn many_keyword_arguments<'py>( + ant: Option<&'_ Bound<'py, PyAny>>, + bear: Option<&'_ Bound<'py, PyAny>>, + cat: Option<&'_ Bound<'py, PyAny>>, + dog: Option<&'_ Bound<'py, PyAny>>, + elephant: Option<&'_ Bound<'py, PyAny>>, + fox: Option<&'_ Bound<'py, PyAny>>, + goat: Option<&'_ Bound<'py, PyAny>>, + horse: Option<&'_ Bound<'py, PyAny>>, + iguana: Option<&'_ Bound<'py, PyAny>>, + jaguar: Option<&'_ Bound<'py, PyAny>>, + koala: Option<&'_ Bound<'py, PyAny>>, + lion: Option<&'_ Bound<'py, PyAny>>, + monkey: Option<&'_ Bound<'py, PyAny>>, + newt: Option<&'_ Bound<'py, PyAny>>, + owl: Option<&'_ Bound<'py, PyAny>>, + penguin: Option<&'_ Bound<'py, PyAny>>, +) { + std::hint::black_box(( + ant, bear, cat, dog, elephant, fox, goat, horse, iguana, jaguar, koala, lion, monkey, newt, + owl, penguin, + )); +} + #[pymodule] pub mod pyfunctions { #[pymodule_export] use super::{ - args_kwargs, none, positional_only, simple, simple_args, simple_args_kwargs, simple_kwargs, - with_custom_type_annotations, with_typed_args, + args_kwargs, many_keyword_arguments, none, positional_only, simple, simple_args, + simple_args_kwargs, simple_kwargs, with_custom_type_annotations, with_typed_args, }; } diff --git a/pytests/stubs/pyfunctions.pyi b/pytests/stubs/pyfunctions.pyi index 251ff160409..d2a4d78d8d9 100644 --- a/pytests/stubs/pyfunctions.pyi +++ b/pytests/stubs/pyfunctions.pyi @@ -1,6 +1,25 @@ import typing def args_kwargs(*args, **kwargs) -> typing.Any: ... +def many_keyword_arguments( + *, + ant: typing.Any | None = None, + bear: typing.Any | None = None, + cat: typing.Any | None = None, + dog: typing.Any | None = None, + elephant: typing.Any | None = None, + fox: typing.Any | None = None, + goat: typing.Any | None = None, + horse: typing.Any | None = None, + iguana: typing.Any | None = None, + jaguar: typing.Any | None = None, + koala: typing.Any | None = None, + lion: typing.Any | None = None, + monkey: typing.Any | None = None, + newt: typing.Any | None = None, + owl: typing.Any | None = None, + penguin: typing.Any | None = None, +) -> typing.Any: ... def none() -> None: ... def positional_only(a: typing.Any, /, b: typing.Any) -> typing.Any: ... def simple( diff --git a/pytests/tests/test_pyfunctions.py b/pytests/tests/test_pyfunctions.py index b3897f289c6..e33d4d6f102 100644 --- a/pytests/tests/test_pyfunctions.py +++ b/pytests/tests/test_pyfunctions.py @@ -1,4 +1,4 @@ -from typing import Tuple +from typing import Any, Tuple from pyo3_pytests import pyfunctions @@ -118,3 +118,55 @@ def test_with_typed_args_rs(benchmark): rust = benchmark(pyfunctions.with_typed_args, True, 1, 1.2, "foo") py = with_typed_args_py(True, 1, 1.2, "foo") assert rust == py + + +def many_keyword_arguments_py( + *, + ant: Any = None, + bear: Any = None, + cat: Any = None, + dog: Any = None, + elephant: Any = None, + fox: Any = None, + goat: Any = None, + horse: Any = None, + iguana: Any = None, + jaguar: Any = None, + koala: Any = None, + lion: Any = None, + monkey: Any = None, + newt: Any = None, + owl: Any = None, + penguin: Any = None, +): ... + + +def call_with_many_keyword_arguments(f) -> Any: + return f( + ant=True, + bear=1, + cat=1.2, + dog="foo", + elephant=None, + fox=8, + goat=9, + horse=10, + iguana=None, + jaguar=None, + koala=None, + lion=11, + owl=None, + penguin=None, + ) + + +def test_many_keyword_arguments_py(benchmark): + benchmark(call_with_many_keyword_arguments, many_keyword_arguments_py) + + +def test_many_keyword_arguments_rs(benchmark): + rust = benchmark( + call_with_many_keyword_arguments, pyfunctions.many_keyword_arguments + ) + py = call_with_many_keyword_arguments(many_keyword_arguments_py) + assert rust == py