From 50d25a9cf0fd45427b830d23c1dfc519a8aedf46 Mon Sep 17 00:00:00 2001 From: Sam Schott Date: Sun, 15 Sep 2024 13:31:49 +0200 Subject: [PATCH] allow passing in args constructors to ensure that all widgets are created on the same thread --- testbed/tests/widgets/conftest.py | 22 ++++++++++++++----- testbed/tests/widgets/test_optioncontainer.py | 2 +- testbed/tests/widgets/test_scrollcontainer.py | 2 +- testbed/tests/widgets/test_splitcontainer.py | 2 +- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/testbed/tests/widgets/conftest.py b/testbed/tests/widgets/conftest.py index e34b2de7f2..74eb7bc44f 100644 --- a/testbed/tests/widgets/conftest.py +++ b/testbed/tests/widgets/conftest.py @@ -1,5 +1,6 @@ import gc import weakref +from typing import Callable, Iterable, ParamSpec, Union from unittest.mock import Mock from pytest import fixture @@ -10,6 +11,8 @@ from ..conftest import skip_on_platforms, xfail_on_platforms from .probe import get_probe +P = ParamSpec("P") + @fixture async def widget(): @@ -84,7 +87,11 @@ def verify_vertical_alignment(): def build_cleanup_test( - widget_class, args=None, kwargs=None, skip_platforms=(), xfail_platforms=() + widget_constructor: Callable[[P], toga.Widget], + args: Union[P.args, Callable[..., P.args]] = (), + kwargs: Union[P.kwargs, Callable[..., P.args], None] = None, + skip_platforms: Iterable[str] = (), + xfail_platforms: Iterable[str] = (), ): async def test_cleanup(): nonlocal args, kwargs @@ -92,10 +99,15 @@ async def test_cleanup(): skip_on_platforms(*skip_platforms) xfail_on_platforms(*xfail_platforms, reason="Leaks memory") - widget = widget_class( - *(args if args is not None else ()), - **(kwargs if kwargs is not None else {}), - ) + if callable(args): + args = args() + + if callable(kwargs): + kwargs = kwargs() + elif args is None: + kwargs = {} + + widget = widget_constructor(*args, **kwargs) ref = weakref.ref(widget) # Args or kwargs may hold a backref to the widget itself, for example if they diff --git a/testbed/tests/widgets/test_optioncontainer.py b/testbed/tests/widgets/test_optioncontainer.py index c3a3ba6ded..a1ac5935ec 100644 --- a/testbed/tests/widgets/test_optioncontainer.py +++ b/testbed/tests/widgets/test_optioncontainer.py @@ -74,7 +74,7 @@ async def widget(content1, content2, content3, on_select_handler): test_cleanup = build_cleanup_test( toga.OptionContainer, - kwargs={"content": [("Tab 1", toga.Box())]}, + kwargs=lambda: {"content": [("Tab 1", toga.Box())]}, xfail_platforms=("android", "iOS", "linux"), ) diff --git a/testbed/tests/widgets/test_scrollcontainer.py b/testbed/tests/widgets/test_scrollcontainer.py index 7b755c559c..217c9c685a 100644 --- a/testbed/tests/widgets/test_scrollcontainer.py +++ b/testbed/tests/widgets/test_scrollcontainer.py @@ -75,7 +75,7 @@ async def widget(content, on_scroll): test_cleanup = build_cleanup_test( toga.ScrollContainer, - kwargs={"content": toga.Box()}, + kwargs=lambda: {"content": toga.Box()}, xfail_platforms=("android", "iOS", "linux"), ) diff --git a/testbed/tests/widgets/test_splitcontainer.py b/testbed/tests/widgets/test_splitcontainer.py index 6477b8500d..51893d8146 100644 --- a/testbed/tests/widgets/test_splitcontainer.py +++ b/testbed/tests/widgets/test_splitcontainer.py @@ -63,7 +63,7 @@ async def widget(content1, content2): test_cleanup = build_cleanup_test( toga.SplitContainer, - kwargs={"content": [toga.Box(), toga.Box()]}, + kwargs=lambda: {"content": [toga.Box(), toga.Box()]}, skip_platforms=("android", "iOS"), )