Public bug reported:

When pysignal trigger magicgui, we found regressions for all archs. The
relevant part of the failures are (from [1]):


 pybuild-autopkgtest
269s I: pybuild base:311: cd /tmp/autopkgtest.RWhG6j/autopkgtest_tmp/build; 
python3.12 -m pytest tests
270s ============================= test session starts 
==============================
270s platform linux -- Python 3.12.4, pytest-7.4.4, pluggy-1.5.0
270s PyQt5 5.15.11 -- Qt runtime 5.15.13 -- Qt compiled 5.15.13
270s rootdir: /tmp/autopkgtest.RWhG6j/autopkgtest_tmp/build
270s configfile: pyproject.toml
270s plugins: qt-4.3.1, xvfb-3.0.0
270s collected 313 items / 3 skipped
270s 
270s tests/test_application.py .                                              [ 
 0%]
270s tests/test_backends.py s.........                                        [ 
 3%]
270s tests/test_container.py ..............                                   [ 
 7%]
270s tests/test_docs.py ss.                                                   [ 
 8%]
270s tests/test_factory.py ..........                                         [ 
12%]
270s tests/test_gui_class.py F.FFF                                            [ 
13%]
271s tests/test_magicgui.py ...................x............................. [ 
29%]
271s                                                                          [ 
29%]
272s tests/test_persistence.py ...                                            [ 
30%]
272s tests/test_signature.py ....                                             [ 
31%]
272s tests/test_table.py ............................sss.........             [ 
44%]
272s tests/test_types.py ...............                                      [ 
49%]
272s tests/test_ui_field.py ..ss....ss.                                       [ 
52%]
273s tests/test_widgets.py ......s.s..ss..s.ss..ss.sss.s..s.........s......s. [ 
68%]
275s s.......s..s............................................................ [ 
91%]
275s ..........................                                               
[100%]
275s 
275s =================================== FAILURES 
===================================
275s ________________________________ test_guiclass 
_________________________________
275s 
275s     def test_guiclass():
275s         """Test that the guiclass decorator works as expected."""
275s         mock = Mock()
275s     
275s         @guiclass
275s         class Foo:
275s             a: int = 1
275s             b: str = "bar"
275s     
275s             @button
275s             def func(self):
275s                 mock(asdict(self))
275s     
275s             # example recommended for type checking
275s             if TYPE_CHECKING:
275s                 gui: ClassVar[Container]
275s                 events: ClassVar[psygnal.SignalGroup]
275s     
275s         foo = Foo()
275s     
275s         assert foo.a == 1
275s         assert foo.b == "bar"
275s     
275s >       assert isinstance(foo.gui, Container)
275s 
275s tests/test_gui_class.py:43: 
275s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
_ _ _ 
275s /usr/lib/python3/dist-packages/magicgui/schema/_guiclass.py:233: in __get__
275s     bind_gui_to_instance(wdg, instance)
275s /usr/lib/python3/dist-packages/magicgui/schema/_guiclass.py:274: in 
bind_gui_to_instance
275s     widget.changed.connect_setattr(
275s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
_ _ _ 
275s 
275s self = <SignalInstance 'changed' on SpinBox(value=1, annotation=<class 
'int'>, name='a')>
275s obj = test_guiclass.<locals>.Foo(a=1, b='bar'), attr = 'a'
275s maxargs = <object object at 0x74ef2bd01e60>
275s 
275s     def connect_setattr(
275s         self,
275s         obj: object,
275s         attr: str,
275s         maxargs: int | None | object = _NULL,
275s         *,
275s         on_ref_error: RefErrorChoice = "warn",
275s         priority: int = 0,
275s     ) -> WeakCallback[None]:
275s         """Bind an object attribute to the emitted value of this signal.
275s     
275s         Equivalent to calling `self.connect(functools.partial(setattr, 
obj, attr))`,
275s         but with additional weakref safety (i.e. a strong reference to 
`obj` will not
275s         be retained). The return object can be used to
275s         [`disconnect()`][psygnal.SignalInstance.disconnect], (or you can 
use
275s         
[`disconnect_setattr()`][psygnal.SignalInstance.disconnect_setattr]).
275s     
275s         Parameters
275s         ----------
275s         obj : object
275s             An object.
275s         attr : str
275s             The name of an attribute on `obj` that should be set to the 
value of this
275s             signal when emitted.
275s         maxargs : Optional[int]
275s             max number of positional args to accept
275s         on_ref_error: {'raise', 'warn', 'ignore'}, optional
275s             What to do if a weak reference cannot be created.  If 'raise', 
a
275s             ReferenceError will be raised.  If 'warn' (default), a warning 
will be
275s             issued and a strong-reference will be used. If 'ignore' a 
strong-reference
275s             will be used (silently).
275s         priority : int
275s             The priority of the callback. This is used to determine the 
order in which
275s             callbacks are called when multiple are connected to the same 
signal.
275s             Higher priority callbacks are called first. Negative values 
are allowed.
275s             The default is 0.
275s     
275s         Returns
275s         -------
275s         Tuple
275s             (weakref.ref, name, callable).  Reference to the object, name 
of the
275s             attribute, and setattr closure.  Can be used to disconnect the 
slot.
275s     
275s         Raises
275s         ------
275s         ValueError
275s             If this is not a single-value signal
275s         AttributeError
275s             If `obj` has no attribute `attr`.
275s     
275s         Examples
275s         --------
275s         >>> class T:
275s         ...     sig = Signal(int)
275s         >>> class SomeObj:
275s         ...     x = 1
275s         >>> t = T()
275s         >>> my_obj = SomeObj()
275s         >>> t.sig.connect_setattr(my_obj, "x")
275s         >>> t.sig.emit(5)
275s         >>> assert my_obj.x == 5
275s         """
275s         if maxargs is _NULL:
275s >           warnings.warn(
275s                 "The default value of maxargs will change from `None` to 
`1` in "
275s                 "version 0.11. To silence this warning, provide an 
explicit value for "
275s                 "maxargs (`None` for current behavior, `1` for future 
behavior).",
275s                 FutureWarning,
275s                 stacklevel=2,
275s             )
275s E           FutureWarning: The default value of maxargs will change from 
`None` to `1` in version 0.11. To silence this warning, provide an explicit 
value for maxargs (`None` for current behavior, `1` for future behavior).
275s 
275s /usr/lib/python3/dist-packages/psygnal/_signal.py:858: FutureWarning
275s __________________________ test_on_existing_dataclass 
__________________________
275s 
275s     def test_on_existing_dataclass():
275s         """Test that the guiclass decorator works on pre-existing 
dataclasses."""
275s     
275s         @guiclass
275s         @dataclass
275s         class Foo:
275s             a: int = 1
275s             b: str = "bar"
275s     
275s         foo = Foo()
275s         assert foo.a == 1
275s         assert foo.b == "bar"
275s >       assert isinstance(foo.gui, Container)
275s 
275s tests/test_gui_class.py:83: 
275s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
_ _ _ 
275s /usr/lib/python3/dist-packages/magicgui/schema/_guiclass.py:233: in __get__
275s     bind_gui_to_instance(wdg, instance)
275s /usr/lib/python3/dist-packages/magicgui/schema/_guiclass.py:274: in 
bind_gui_to_instance
275s     widget.changed.connect_setattr(
275s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
_ _ _ 
275s 
275s self = <SignalInstance 'changed' on SpinBox(value=1, annotation=<class 
'int'>, name='a')>
275s obj = test_on_existing_dataclass.<locals>.Foo(a=1, b='bar'), attr = 'a'
275s maxargs = <object object at 0x74ef2bd01e60>
275s 
275s     def connect_setattr(
275s         self,
275s         obj: object,
275s         attr: str,
275s         maxargs: int | None | object = _NULL,
275s         *,
275s         on_ref_error: RefErrorChoice = "warn",
275s         priority: int = 0,
275s     ) -> WeakCallback[None]:
275s         """Bind an object attribute to the emitted value of this signal.
275s     
275s         Equivalent to calling `self.connect(functools.partial(setattr, 
obj, attr))`,
275s         but with additional weakref safety (i.e. a strong reference to 
`obj` will not
275s         be retained). The return object can be used to
275s         [`disconnect()`][psygnal.SignalInstance.disconnect], (or you can 
use
275s         
[`disconnect_setattr()`][psygnal.SignalInstance.disconnect_setattr]).
275s     
275s         Parameters
275s         ----------
275s         obj : object
275s             An object.
275s         attr : str
275s             The name of an attribute on `obj` that should be set to the 
value of this
275s             signal when emitted.
275s         maxargs : Optional[int]
275s             max number of positional args to accept
275s         on_ref_error: {'raise', 'warn', 'ignore'}, optional
275s             What to do if a weak reference cannot be created.  If 'raise', 
a
275s             ReferenceError will be raised.  If 'warn' (default), a warning 
will be
275s             issued and a strong-reference will be used. If 'ignore' a 
strong-reference
275s             will be used (silently).
275s         priority : int
275s             The priority of the callback. This is used to determine the 
order in which
275s             callbacks are called when multiple are connected to the same 
signal.
275s             Higher priority callbacks are called first. Negative values 
are allowed.
275s             The default is 0.
275s     
275s         Returns
275s         -------
275s         Tuple
275s             (weakref.ref, name, callable).  Reference to the object, name 
of the
275s             attribute, and setattr closure.  Can be used to disconnect the 
slot.
275s     
275s         Raises
275s         ------
275s         ValueError
275s             If this is not a single-value signal
275s         AttributeError
275s             If `obj` has no attribute `attr`.
275s     
275s         Examples
275s         --------
275s         >>> class T:
275s         ...     sig = Signal(int)
275s         >>> class SomeObj:
275s         ...     x = 1
275s         >>> t = T()
275s         >>> my_obj = SomeObj()
275s         >>> t.sig.connect_setattr(my_obj, "x")
275s         >>> t.sig.emit(5)
275s         >>> assert my_obj.x == 5
275s         """
275s         if maxargs is _NULL:
275s >           warnings.warn(
275s                 "The default value of maxargs will change from `None` to 
`1` in "
275s                 "version 0.11. To silence this warning, provide an 
explicit value for "
275s                 "maxargs (`None` for current behavior, `1` for future 
behavior).",
275s                 FutureWarning,
275s                 stacklevel=2,
275s             )
275s E           FutureWarning: The default value of maxargs will change from 
`None` to `1` in version 0.11. To silence this warning, provide an explicit 
value for maxargs (`None` for current behavior, `1` for future behavior).
275s 
275s /usr/lib/python3/dist-packages/psygnal/_signal.py:858: FutureWarning
275s _____________________________ test_slots_guiclass 
______________________________
275s 
275s     @pytest.mark.skipif(sys.version_info < (3, 10), reason="slots are 
python3.10 or higher")
275s     def test_slots_guiclass():
275s         """Test that the guiclass decorator works as expected."""
275s     
275s         psyg_v = tuple(int(x.split("r")[0]) for x in 
psygnal.__version__.split(".")[:3])
275s         old_psygnal = psyg_v < (0, 6, 1)
275s     
275s         @guiclass(slots=True)
275s         class Foo:
275s             a: int = 1
275s             b: str = "bar"
275s     
275s         foo = Foo()
275s     
275s         with (
275s             pytest.warns(UserWarning, match="Please update psygnal")
275s             if old_psygnal
275s             else contextlib.nullcontext()
275s         ):
275s >           gui = foo.gui
275s 
275s tests/test_gui_class.py:105: 
275s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
_ _ _ 
275s /usr/lib/python3/dist-packages/magicgui/schema/_guiclass.py:233: in __get__
275s     bind_gui_to_instance(wdg, instance)
275s /usr/lib/python3/dist-packages/magicgui/schema/_guiclass.py:274: in 
bind_gui_to_instance
275s     widget.changed.connect_setattr(
275s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
_ _ _ 
275s 
275s self = <SignalInstance 'changed' on SpinBox(value=1, annotation=<class 
'int'>, name='a')>
275s obj = test_slots_guiclass.<locals>.Foo(a=1, b='bar'), attr = 'a'
275s maxargs = <object object at 0x74ef2bd01e60>
275s 
275s     def connect_setattr(
275s         self,
275s         obj: object,
275s         attr: str,
275s         maxargs: int | None | object = _NULL,
275s         *,
275s         on_ref_error: RefErrorChoice = "warn",
275s         priority: int = 0,
275s     ) -> WeakCallback[None]:
275s         """Bind an object attribute to the emitted value of this signal.
275s     
275s         Equivalent to calling `self.connect(functools.partial(setattr, 
obj, attr))`,
275s         but with additional weakref safety (i.e. a strong reference to 
`obj` will not
275s         be retained). The return object can be used to
275s         [`disconnect()`][psygnal.SignalInstance.disconnect], (or you can 
use
275s         
[`disconnect_setattr()`][psygnal.SignalInstance.disconnect_setattr]).
275s     
275s         Parameters
275s         ----------
275s         obj : object
275s             An object.
275s         attr : str
275s             The name of an attribute on `obj` that should be set to the 
value of this
275s             signal when emitted.
275s         maxargs : Optional[int]
275s             max number of positional args to accept
275s         on_ref_error: {'raise', 'warn', 'ignore'}, optional
275s             What to do if a weak reference cannot be created.  If 'raise', 
a
275s             ReferenceError will be raised.  If 'warn' (default), a warning 
will be
275s             issued and a strong-reference will be used. If 'ignore' a 
strong-reference
275s             will be used (silently).
275s         priority : int
275s             The priority of the callback. This is used to determine the 
order in which
275s             callbacks are called when multiple are connected to the same 
signal.
275s             Higher priority callbacks are called first. Negative values 
are allowed.
275s             The default is 0.
275s     
275s         Returns
275s         -------
275s         Tuple
275s             (weakref.ref, name, callable).  Reference to the object, name 
of the
275s             attribute, and setattr closure.  Can be used to disconnect the 
slot.
275s     
275s         Raises
275s         ------
275s         ValueError
275s             If this is not a single-value signal
275s         AttributeError
275s             If `obj` has no attribute `attr`.
275s     
275s         Examples
275s         --------
275s         >>> class T:
275s         ...     sig = Signal(int)
275s         >>> class SomeObj:
275s         ...     x = 1
275s         >>> t = T()
275s         >>> my_obj = SomeObj()
275s         >>> t.sig.connect_setattr(my_obj, "x")
275s         >>> t.sig.emit(5)
275s         >>> assert my_obj.x == 5
275s         """
275s         if maxargs is _NULL:
275s >           warnings.warn(
275s                 "The default value of maxargs will change from `None` to 
`1` in "
275s                 "version 0.11. To silence this warning, provide an 
explicit value for "
275s                 "maxargs (`None` for current behavior, `1` for future 
behavior).",
275s                 FutureWarning,
275s                 stacklevel=2,
275s             )
275s E           FutureWarning: The default value of maxargs will change from 
`None` to `1` in version 0.11. To silence this warning, provide an explicit 
value for maxargs (`None` for current behavior, `1` for future behavior).
275s 
275s /usr/lib/python3/dist-packages/psygnal/_signal.py:858: FutureWarning
275s ____________________________ test_guiclass_as_class 
____________________________
275s 
275s     def test_guiclass_as_class():
275s         # variant on @guiclass, using class instead of decorator
275s         class T2(GuiClass):
275s             x: int
275s             y: str = "hi"
275s     
275s             @button
275s             def foo(self):
275s                 return asdict(self)
275s     
275s         t2 = T2(1)
275s         assert t2.x == 1
275s         assert t2.y == "hi"
275s >       assert t2.gui.x.value == 1
275s 
275s tests/test_gui_class.py:141: 
275s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
_ _ _ 
275s /usr/lib/python3/dist-packages/magicgui/schema/_guiclass.py:233: in __get__
275s     bind_gui_to_instance(wdg, instance)
275s /usr/lib/python3/dist-packages/magicgui/schema/_guiclass.py:274: in 
bind_gui_to_instance
275s     widget.changed.connect_setattr(
275s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
_ _ _ 
275s 
275s self = <SignalInstance 'changed' on SpinBox(value=1, annotation=<class 
'int'>, name='x')>
275s obj = test_guiclass_as_class.<locals>.T2(x=1, y='hi'), attr = 'x'
275s maxargs = <object object at 0x74ef2bd01e60>
275s 
275s     def connect_setattr(
275s         self,
275s         obj: object,
275s         attr: str,
275s         maxargs: int | None | object = _NULL,
275s         *,
275s         on_ref_error: RefErrorChoice = "warn",
275s         priority: int = 0,
275s     ) -> WeakCallback[None]:
275s         """Bind an object attribute to the emitted value of this signal.
275s     
275s         Equivalent to calling `self.connect(functools.partial(setattr, 
obj, attr))`,
275s         but with additional weakref safety (i.e. a strong reference to 
`obj` will not
275s         be retained). The return object can be used to
275s         [`disconnect()`][psygnal.SignalInstance.disconnect], (or you can 
use
275s         
[`disconnect_setattr()`][psygnal.SignalInstance.disconnect_setattr]).
275s     
275s         Parameters
275s         ----------
275s         obj : object
275s             An object.
275s         attr : str
275s             The name of an attribute on `obj` that should be set to the 
value of this
275s             signal when emitted.
275s         maxargs : Optional[int]
275s             max number of positional args to accept
275s         on_ref_error: {'raise', 'warn', 'ignore'}, optional
275s             What to do if a weak reference cannot be created.  If 'raise', 
a
275s             ReferenceError will be raised.  If 'warn' (default), a warning 
will be
275s             issued and a strong-reference will be used. If 'ignore' a 
strong-reference
275s             will be used (silently).
275s         priority : int
275s             The priority of the callback. This is used to determine the 
order in which
275s             callbacks are called when multiple are connected to the same 
signal.
275s             Higher priority callbacks are called first. Negative values 
are allowed.
275s             The default is 0.
275s     
275s         Returns
275s         -------
275s         Tuple
275s             (weakref.ref, name, callable).  Reference to the object, name 
of the
275s             attribute, and setattr closure.  Can be used to disconnect the 
slot.
275s     
275s         Raises
275s         ------
275s         ValueError
275s             If this is not a single-value signal
275s         AttributeError
275s             If `obj` has no attribute `attr`.
275s     
275s         Examples
275s         --------
275s         >>> class T:
275s         ...     sig = Signal(int)
275s         >>> class SomeObj:
275s         ...     x = 1
275s         >>> t = T()
275s         >>> my_obj = SomeObj()
275s         >>> t.sig.connect_setattr(my_obj, "x")
275s         >>> t.sig.emit(5)
275s         >>> assert my_obj.x == 5
275s         """
275s         if maxargs is _NULL:
275s >           warnings.warn(
275s                 "The default value of maxargs will change from `None` to 
`1` in "
275s                 "version 0.11. To silence this warning, provide an 
explicit value for "
275s                 "maxargs (`None` for current behavior, `1` for future 
behavior).",
275s                 FutureWarning,
275s                 stacklevel=2,
275s             )
275s E           FutureWarning: The default value of maxargs will change from 
`None` to `1` in version 0.11. To silence this warning, provide an explicit 
value for maxargs (`None` for current behavior, `1` for future behavior).
275s 
275s /usr/lib/python3/dist-packages/psygnal/_signal.py:858: FutureWarning
275s =========================== short test summary info 
============================
275s FAILED tests/test_gui_class.py::test_guiclass - FutureWarning: The default 
va...
275s FAILED tests/test_gui_class.py::test_on_existing_dataclass - 
FutureWarning: T...
275s FAILED tests/test_gui_class.py::test_slots_guiclass - FutureWarning: The 
defa...
275s FAILED tests/test_gui_class.py::test_guiclass_as_class - FutureWarning: 
The d...
275s ============= 4 failed, 279 passed, 32 skipped, 1 xfailed in 5.97s 
=============
276s E: pybuild pybuild:389: test: plugin pyproject failed with: exit code=1: 
cd /tmp/autopkgtest.RWhG6j/autopkgtest_tmp/build; python3.12 -m pytest tests
276s pybuild-autopkgtest: error: pybuild --autopkgtest --test-pytest -i 
python{version} -p 3.12 returned exit code 13
276s make: *** [/tmp/dc8bKKY9VU/run:4: pybuild-autopkgtest] Error 25


On upstream, this test are passing [2] with pyside6 (installing from pip). I 
tried adding python3-pyqt and python3-pyqt6 to d/control to see if this 
overcomes it and mimic the upstream's actions [3], with no luck 


[1] 
https://objectstorage.prodstack5.canonical.com/swift/v1/AUTH_0f9aae918d5b4744bf7b827671c86842/autopkgtest-oracular/oracular/amd64/m/magicgui/20240804_072247_72842@/log.gz
[2] 
https://github.com/pyapp-kit/magicgui/actions/runs/10240968558/job/28328574711
[3] https://github.com/pyapp-kit/magicgui/actions/runs/10240968558/workflow

** Affects: magicgui (Ubuntu)
     Importance: Undecided
         Status: New

** Affects: magicgui (Debian)
     Importance: Unknown
         Status: Unknown


** Tags: update-excuse

** Bug watch added: Debian Bug tracker #1074724
   https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1074724

** Also affects: magicgui (Debian) via
   https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1074724
   Importance: Unknown
       Status: Unknown

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2076095

Title:
  Tests failing with python 3.12

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/magicgui/+bug/2076095/+subscriptions


-- 
ubuntu-bugs mailing list
ubuntu-bugs@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to