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
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs