From 3f222f142b73cfafb3d0bd1b00f9c749b123f688 Mon Sep 17 00:00:00 2001 From: Rohan Patnaik Date: Fri, 22 May 2026 12:45:58 +0530 Subject: [PATCH 1/2] fix: ignore keyword-only handler parameters --- playwright/_impl/_impl_to_api_mapping.py | 18 ++++++++++++++- tests/common/test_impl_to_api_mapping.py | 29 ++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 tests/common/test_impl_to_api_mapping.py diff --git a/playwright/_impl/_impl_to_api_mapping.py b/playwright/_impl/_impl_to_api_mapping.py index e26d22025..8b3cbd756 100644 --- a/playwright/_impl/_impl_to_api_mapping.py +++ b/playwright/_impl/_impl_to_api_mapping.py @@ -119,7 +119,23 @@ def to_impl( def wrap_handler(self, handler: Callable[..., Any]) -> Callable[..., None]: def wrapper_func(*args: Any) -> Any: - arg_count = len(inspect.signature(handler).parameters) + parameters = inspect.signature(handler).parameters + has_varargs = any( + parameter.kind == inspect.Parameter.VAR_POSITIONAL + for parameter in parameters.values() + ) + arg_count = ( + len(args) + if has_varargs + else sum( + parameter.kind + in ( + inspect.Parameter.POSITIONAL_ONLY, + inspect.Parameter.POSITIONAL_OR_KEYWORD, + ) + for parameter in parameters.values() + ) + ) return handler( *list(map(lambda a: self.from_maybe_impl(a), args))[:arg_count] ) diff --git a/tests/common/test_impl_to_api_mapping.py b/tests/common/test_impl_to_api_mapping.py new file mode 100644 index 000000000..74142bc3f --- /dev/null +++ b/tests/common/test_impl_to_api_mapping.py @@ -0,0 +1,29 @@ +# Copyright (c) Microsoft Corporation. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import List, Optional + +from playwright._impl._impl_to_api_mapping import ImplToApiMapping + + +def test_wrap_handler_ignores_keyword_only_parameters() -> None: + calls: List[Optional[int]] = [] + + class Input: + def blur(self, *, timeout: Optional[int] = None) -> None: + calls.append(timeout) + + ImplToApiMapping().wrap_handler(Input().blur)("locator") + + assert calls == [None] From 7ef31fb4e21cb4952415c552f3237f06a7f74ae1 Mon Sep 17 00:00:00 2001 From: Rohan Patnaik Date: Tue, 2 Jun 2026 04:12:39 +0530 Subject: [PATCH 2/2] test: cover varargs handler wrapping --- tests/common/test_impl_to_api_mapping.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/common/test_impl_to_api_mapping.py b/tests/common/test_impl_to_api_mapping.py index 74142bc3f..387ae1cc6 100644 --- a/tests/common/test_impl_to_api_mapping.py +++ b/tests/common/test_impl_to_api_mapping.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import List, Optional +from typing import List, Optional, Tuple from playwright._impl._impl_to_api_mapping import ImplToApiMapping @@ -27,3 +27,14 @@ def blur(self, *, timeout: Optional[int] = None) -> None: ImplToApiMapping().wrap_handler(Input().blur)("locator") assert calls == [None] + + +def test_wrap_handler_passes_all_args_for_varargs_handler() -> None: + calls: List[Tuple[object, ...]] = [] + + def handler(*args: object) -> None: + calls.append(args) + + ImplToApiMapping().wrap_handler(handler)("a", "b", "c") + + assert calls == [("a", "b", "c")]