Python字典转GLib Variant失败:NetworkManager DBus调用报错
使用pydbus调用NetworkManager的AddAndActivateConnection连接Wi-Fi时GLib Variant格式错误问题解决
问题背景
尝试用pydbus库调用NetworkManager的DBus方法AddAndActivateConnection连接Wi-Fi,但生成符合格式说明符a{sa{sv}}的GLib Variant时遇到问题,报错提示期望GLib.Variant类型却传入了字符串。
初始代码
from pydbus import SystemBus bus = SystemBus() nm = bus.get("org.freedesktop.NetworkManager") # 查找Wi-Fi设备 wifi_path = None for dev_path in nm.GetDevices(): dev = bus.get("org.freedesktop.NetworkManager", dev_path) if dev.DeviceType == 2: wifi_path = dev_path break if not wifi_path: raise RuntimeError("未找到Wi-Fi设备。") ssid = "MyWiFi" password = "mypassword123" settings = { 'connection': { 'id': ssid, 'type': '802-11-wireless', }, '802-11-wireless': { 'ssid': ssid, 'mode': 'infrastructure', }, '802-11-wireless-security': { 'key-mgmt': 'wpa-psk', 'psk': password, }, 'ipv4': { 'method': 'auto', }, 'ipv6': { 'method': 'ignore', } } nm.AddAndActivateConnection(settings, wifi_path, "/")
错误信息
Traceback (most recent call last): File "/root/connect3.py", line 43, in <module> nm.AddAndActivateConnection(settings, wifi_path, "/") ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/pydbus/proxy_method.py", line 74, in __call__ self._iface_name, self.__name__, GLib.Variant(self._sinargs, args), GLib.VariantType.new(self._soutargs), ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/gi/overrides/GLib.py", line 189, in __new__ v = creator._create(format_string, value) File "/usr/lib/python3/dist-packages/gi/overrides/GLib.py", line 150, in _create builder.add_value(self._create(dup, i)) ~~~~~~~~~~~^^^^^^^^ File "/usr/lib/python3/dist-packages/gi/overrides/GLib.py", line 145, in _create builder.add_value(self._create(element_type, i)) ~~~~~~~~~~~^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/gi/overrides/GLib.py", line 150, in _create builder.add_value(self._create(dup, i)) ~~~~~~~~~~~^^^^^^^^ File "/usr/lib/python3/dist-packages/gi/overrides/GLib.py", line 145, in _create builder.add_value(self._create(element_type, i)) ~~~~~~~~~~~^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/gi/overrides/GLib.py", line 150, in _create builder.add_value(self._create(dup, i)) ~~~~~~~~~~~^^^^^^^^ File "/usr/lib/python3/dist-packages/gi/overrides/GLib.py", line 118, in _create return self._LEAF_CONSTRUCTORS[format](value) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^ TypeError: argument value: Expected GLib.Variant, but got str
系统信息:
- 架构:aarch64
- 操作系统:Debian 13 (trixie)
- Python版本:3.13.5
解决方法
问题核心是settings字典中的值未正确包装为GLib Variant对象,且SSID需要以字节数组类型(ay)传递而非字符串。修正后的完整代码如下:
from pydbus import SystemBus from gi.repository import GLib bus = SystemBus() nm = bus.get("org.freedesktop.NetworkManager") # 查找Wi-Fi设备 wifi_path = None for dev_path in nm.GetDevices(): dev = bus.get("org.freedesktop.NetworkManager", dev_path) if dev.DeviceType == 2: wifi_path = dev_path break if not wifi_path: raise RuntimeError("未找到Wi-Fi设备。") ssid = "MyWiFi" password = "mypassword123" settings = { "connection": { "id": GLib.Variant('s', ssid), "type": GLib.Variant('s', "802-11-wireless"), }, "802-11-wireless": { "ssid": GLib.Variant('ay', bytearray(ssid, 'utf-8')), "mode": GLib.Variant('s', "infrastructure"), }, "802-11-wireless-security": { "key-mgmt": GLib.Variant('s', "wpa-psk"), "psk": GLib.Variant('s', password), }, "ipv4": {"method": GLib.Variant('s', "auto")}, "ipv6": {"method": GLib.Variant('s', "ignore")}, } nm.AddAndActivateConnection(settings, wifi_path, "/")
关键注意事项
- 所有配置项的值必须用
GLib.Variant包装,并指定对应类型标识(如字符串用s,字节数组用ay) - SSID不能直接传递字符串类型的Variant,必须转为字节数组的
ay类型,否则会触发其他未知错误
内容的提问来源于stack exchange,提问作者owndampu
相关产品推荐
相关产品推荐

