From 4b6437c453dfd5004d9a5937e0b3edff79c2d6ca Mon Sep 17 00:00:00 2001 From: proneon267 Date: Sun, 5 Jan 2025 05:21:59 -0500 Subject: [PATCH 1/7] Fix `on_scroll` in `ScrollContainer` --- core/src/toga/widgets/scrollcontainer.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/core/src/toga/widgets/scrollcontainer.py b/core/src/toga/widgets/scrollcontainer.py index 5469731ba4..46ae2f06a7 100644 --- a/core/src/toga/widgets/scrollcontainer.py +++ b/core/src/toga/widgets/scrollcontainer.py @@ -40,16 +40,19 @@ def __init__( :param on_scroll: Initial :any:`on_scroll` handler. :param content: The content to display in the scroll window. """ + + # This event gets called early on during impl initialization, + # hence set it up before calling initialization on base class. + self.on_scroll = on_scroll + super().__init__(id=id, style=style) self._content: Widget | None = None - self.on_scroll = None # Set all attributes self.vertical = vertical self.horizontal = horizontal self.content = content - self.on_scroll = on_scroll def _create(self) -> Any: return self.factory.ScrollContainer(interface=self) From 529dec2c45633e64e6dca29c9f2b5a148a543650 Mon Sep 17 00:00:00 2001 From: proneon267 Date: Sun, 5 Jan 2025 05:36:17 -0500 Subject: [PATCH 2/7] Add changelog --- changes/3071.misc.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 changes/3071.misc.rst diff --git a/changes/3071.misc.rst b/changes/3071.misc.rst new file mode 100644 index 0000000000..a029af733c --- /dev/null +++ b/changes/3071.misc.rst @@ -0,0 +1 @@ +An ``AttributeError`` raised by ``ScrollContainer()`` for ``on_scroll`` during initialization is now fixed. From 4b8e05dcd9a84a99eeb5b3f32cf04a9d9887cbd9 Mon Sep 17 00:00:00 2001 From: proneon267 Date: Sun, 5 Jan 2025 05:39:06 -0500 Subject: [PATCH 3/7] pre-commit fix --- changes/3071.misc.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changes/3071.misc.rst b/changes/3071.misc.rst index a029af733c..5263441edc 100644 --- a/changes/3071.misc.rst +++ b/changes/3071.misc.rst @@ -1 +1 @@ -An ``AttributeError`` raised by ``ScrollContainer()`` for ``on_scroll`` during initialization is now fixed. +An ``AttributeError`` raised by ``ScrollContainer()`` for ``on_scroll`` during initialization is now fixed. From d7b9df591f15234c136b063c26fa6458d789733d Mon Sep 17 00:00:00 2001 From: proneon267 Date: Sun, 5 Jan 2025 06:12:38 -0500 Subject: [PATCH 4/7] Fix `on_scroll` in `ScrollContainer` on `gtk` --- core/src/toga/widgets/scrollcontainer.py | 6 ++---- gtk/src/toga_gtk/widgets/scrollcontainer.py | 11 ++++++++++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/core/src/toga/widgets/scrollcontainer.py b/core/src/toga/widgets/scrollcontainer.py index 46ae2f06a7..fae3c2a27c 100644 --- a/core/src/toga/widgets/scrollcontainer.py +++ b/core/src/toga/widgets/scrollcontainer.py @@ -41,18 +41,16 @@ def __init__( :param content: The content to display in the scroll window. """ - # This event gets called early on during impl initialization, - # hence set it up before calling initialization on base class. - self.on_scroll = on_scroll - super().__init__(id=id, style=style) self._content: Widget | None = None + self.on_scroll = None # Set all attributes self.vertical = vertical self.horizontal = horizontal self.content = content + self.on_scroll = on_scroll def _create(self) -> Any: return self.factory.ScrollContainer(interface=self) diff --git a/gtk/src/toga_gtk/widgets/scrollcontainer.py b/gtk/src/toga_gtk/widgets/scrollcontainer.py index 33cebbb1fc..c4e629ba08 100644 --- a/gtk/src/toga_gtk/widgets/scrollcontainer.py +++ b/gtk/src/toga_gtk/widgets/scrollcontainer.py @@ -24,7 +24,16 @@ def create(self): self.native.add(self.document_container) def gtk_on_changed(self, *args): - self.interface.on_scroll() + # This event gets called early on during impl initialization, + # even before the interface is initialized completely. Hence, + # it raises an Attribute error on `on_scroll` property during + # the early stages, so detect it and do a no-op in such cases. + try: + self.interface.on_scroll + except AttributeError: + pass + else: + self.interface.on_scroll() def set_content(self, widget): self.document_container.content = widget From 9a70f7b42c79e7cb7b36f659d02b85d50d9e3abb Mon Sep 17 00:00:00 2001 From: proneon267 Date: Sun, 5 Jan 2025 06:28:40 -0500 Subject: [PATCH 5/7] Use first Fix --- core/src/toga/widgets/canvas/canvas.py | 4 ++-- core/src/toga/widgets/numberinput.py | 4 ++-- core/src/toga/widgets/optioncontainer.py | 3 ++- core/src/toga/widgets/scrollcontainer.py | 4 ++-- core/src/toga/widgets/selection.py | 3 ++- core/src/toga/widgets/splitcontainer.py | 2 +- gtk/src/toga_gtk/widgets/scrollcontainer.py | 11 +---------- 7 files changed, 12 insertions(+), 19 deletions(-) diff --git a/core/src/toga/widgets/canvas/canvas.py b/core/src/toga/widgets/canvas/canvas.py index 0eb4f7e778..5d5efd3f45 100644 --- a/core/src/toga/widgets/canvas/canvas.py +++ b/core/src/toga/widgets/canvas/canvas.py @@ -85,8 +85,6 @@ def __init__( :param on_alt_release: Initial :any:`on_alt_release` handler. :param on_alt_drag: Initial :any:`on_alt_drag` handler. """ - super().__init__(id=id, style=style) - self._context = Context(canvas=self) # Set all the properties @@ -99,6 +97,8 @@ def __init__( self.on_alt_release = on_alt_release self.on_alt_drag = on_alt_drag + super().__init__(id=id, style=style) + def _create(self) -> Any: return self.factory.Canvas(interface=self) diff --git a/core/src/toga/widgets/numberinput.py b/core/src/toga/widgets/numberinput.py index 318da052ce..d682e16a1e 100644 --- a/core/src/toga/widgets/numberinput.py +++ b/core/src/toga/widgets/numberinput.py @@ -108,8 +108,6 @@ def __init__( :param on_change: A handler that will be invoked when the value of the widget changes. """ - super().__init__(id=id, style=style) - # The initial setting of min requires calling get_value(), # which in turn interrogates min. Prime those values with # an empty starting value @@ -118,6 +116,8 @@ def __init__( self.on_change = None + super().__init__(id=id, style=style) + self.readonly = readonly self.step = step self.min = min diff --git a/core/src/toga/widgets/optioncontainer.py b/core/src/toga/widgets/optioncontainer.py index 9cb1d961ef..ec309dbf20 100644 --- a/core/src/toga/widgets/optioncontainer.py +++ b/core/src/toga/widgets/optioncontainer.py @@ -393,10 +393,11 @@ def __init__( ` to display in the OptionContainer. :param on_select: Initial :any:`on_select` handler. """ - super().__init__(id=id, style=style) self._content = OptionList(self) self.on_select = None + super().__init__(id=id, style=style) + if content is not None: for item in content: if isinstance(item, OptionItem): diff --git a/core/src/toga/widgets/scrollcontainer.py b/core/src/toga/widgets/scrollcontainer.py index fae3c2a27c..0639997501 100644 --- a/core/src/toga/widgets/scrollcontainer.py +++ b/core/src/toga/widgets/scrollcontainer.py @@ -41,11 +41,11 @@ def __init__( :param content: The content to display in the scroll window. """ - super().__init__(id=id, style=style) - self._content: Widget | None = None self.on_scroll = None + super().__init__(id=id, style=style) + # Set all attributes self.vertical = vertical self.horizontal = horizontal diff --git a/core/src/toga/widgets/selection.py b/core/src/toga/widgets/selection.py index 171975460f..161b561513 100644 --- a/core/src/toga/widgets/selection.py +++ b/core/src/toga/widgets/selection.py @@ -46,13 +46,14 @@ def __init__( :param on_change: Initial :any:`on_change` handler. :param enabled: Whether the user can interact with the widget. """ - super().__init__(id=id, style=style) self._items: SourceT | ListSource self.on_change = None # needed for _impl initialization self._accessor = accessor + super().__init__(id=id, style=style) + self.items = items if value: self.value = value diff --git a/core/src/toga/widgets/splitcontainer.py b/core/src/toga/widgets/splitcontainer.py index 29493e856e..0024cddd1c 100644 --- a/core/src/toga/widgets/splitcontainer.py +++ b/core/src/toga/widgets/splitcontainer.py @@ -42,8 +42,8 @@ def __init__( :param content: Initial :any:`SplitContainer content ` of the container. Defaults to both panels being empty. """ - super().__init__(id=id, style=style) self._content: list[SplitContainerContentT] = [None, None] + super().__init__(id=id, style=style) if content: self.content = content diff --git a/gtk/src/toga_gtk/widgets/scrollcontainer.py b/gtk/src/toga_gtk/widgets/scrollcontainer.py index c4e629ba08..33cebbb1fc 100644 --- a/gtk/src/toga_gtk/widgets/scrollcontainer.py +++ b/gtk/src/toga_gtk/widgets/scrollcontainer.py @@ -24,16 +24,7 @@ def create(self): self.native.add(self.document_container) def gtk_on_changed(self, *args): - # This event gets called early on during impl initialization, - # even before the interface is initialized completely. Hence, - # it raises an Attribute error on `on_scroll` property during - # the early stages, so detect it and do a no-op in such cases. - try: - self.interface.on_scroll - except AttributeError: - pass - else: - self.interface.on_scroll() + self.interface.on_scroll() def set_content(self, widget): self.document_container.content = widget From 944427622bb099ffe7387c981862476dab40f7be Mon Sep 17 00:00:00 2001 From: proneon267 Date: Sun, 5 Jan 2025 07:40:25 -0500 Subject: [PATCH 6/7] Update Changelog --- changes/3071.misc.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changes/3071.misc.rst b/changes/3071.misc.rst index 5263441edc..9ce56b3e89 100644 --- a/changes/3071.misc.rst +++ b/changes/3071.misc.rst @@ -1 +1 @@ -An ``AttributeError`` raised by ``ScrollContainer()`` for ``on_scroll`` during initialization is now fixed. +Essential attributes on the widgets' interface are now primed out before initialization of widgets' impl. From 9856e307f872b4134daa6341fd83ce3f70258c13 Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Mon, 6 Jan 2025 08:35:11 +0800 Subject: [PATCH 7/7] Correct instantiation order for canvas. --- core/src/toga/widgets/canvas/canvas.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/toga/widgets/canvas/canvas.py b/core/src/toga/widgets/canvas/canvas.py index 5d5efd3f45..e23913299a 100644 --- a/core/src/toga/widgets/canvas/canvas.py +++ b/core/src/toga/widgets/canvas/canvas.py @@ -87,6 +87,8 @@ def __init__( """ self._context = Context(canvas=self) + super().__init__(id=id, style=style) + # Set all the properties self.on_resize = on_resize self.on_press = on_press @@ -97,8 +99,6 @@ def __init__( self.on_alt_release = on_alt_release self.on_alt_drag = on_alt_drag - super().__init__(id=id, style=style) - def _create(self) -> Any: return self.factory.Canvas(interface=self)