From f06947313bc6eac2a287b21459405ccdba464f2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Thu, 19 Jun 2025 18:36:45 +0200 Subject: [PATCH 1/3] Preserve stateless property based on type annotation Otherwise all values would be serialized to str. --- qubes/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qubes/__init__.py b/qubes/__init__.py index c0e67986d..c533c9d36 100644 --- a/qubes/__init__.py +++ b/qubes/__init__.py @@ -505,11 +505,13 @@ def bool(self, prop, value): def stateless_property(func): """Decorator similar to :py:class:`builtins.property`, but for properties exposed through management API (including qvm-prefs etc)""" + prop_type = func.__annotations__.get('return', None) return property( func.__name__, setter=property.forbidden, saver=property.dontsave, default=func, + type=prop_type, doc=func.__doc__, ) From a3aa53ba01be441848327b20df7283af4e02260d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Thu, 19 Jun 2025 18:48:10 +0200 Subject: [PATCH 2/3] Add type annotations to some stateless properties Following the previous commit, this improves serialization. --- qubes/vm/qubesvm.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qubes/vm/qubesvm.py b/qubes/vm/qubesvm.py index 9e05ce37d..4d8a71628 100644 --- a/qubes/vm/qubesvm.py +++ b/qubes/vm/qubesvm.py @@ -950,7 +950,7 @@ def __str__(self): # VMM-related @qubes.stateless_property - def xid(self): + def xid(self) -> int: """Xen ID. Or not Xen, but ID. @@ -970,7 +970,7 @@ def xid(self): raise @qubes.stateless_property - def stubdom_uuid(self): + def stubdom_uuid(self) -> str: stubdom_xid = self.stubdom_xid if stubdom_xid == -1: return "" @@ -981,7 +981,7 @@ def stubdom_uuid(self): return stubdom_uuid[4:].decode("ascii", "strict") @qubes.stateless_property - def stubdom_xid(self): + def stubdom_xid(self) -> int: if not self.is_running(): return -1 @@ -2653,7 +2653,7 @@ def start_time(self): return None @qubes.stateless_property - def icon(self): + def icon(self) -> str: """freedesktop icon name, suitable for use in :py:meth:`PyQt4.QtGui.QIcon.fromTheme`""" raw_icon_name = self.label.name From 7279dbc29a09ffa2eeb35d91b962c11fd3770821 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Thu, 19 Jun 2025 18:51:03 +0200 Subject: [PATCH 3/3] tests: type preservation on stateless property --- qubes/tests/api_admin.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/qubes/tests/api_admin.py b/qubes/tests/api_admin.py index b4abb78c3..187dc68f1 100644 --- a/qubes/tests/api_admin.py +++ b/qubes/tests/api_admin.py @@ -261,6 +261,11 @@ def test_021_vm_property_get_int(self): b"admin.vm.property.Get", b"test-vm1", b"vcpus" ) self.assertEqual(value, "default=True type=int 2") + # check also if type is preserved on stateless property + value = self.call_mgmt_func( + b"admin.vm.property.Get", b"test-vm1", b"xid" + ) + self.assertEqual(value, "default=True type=int -1") def test_022_vm_property_get_bool(self): value = self.call_mgmt_func(