You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 15:53:11