From c884b1410d6a2e89f091af044942f1c788699e95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Behrmann?= Date: Wed, 25 Feb 2026 10:26:15 +0100 Subject: [PATCH 1/7] ukify: factor out method for value parsing in ConfigItem --- src/ukify/ukify.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/ukify/ukify.py b/src/ukify/ukify.py index 4a13019e24..0377c57ea7 100755 --- a/src/ukify/ukify.py +++ b/src/ukify/ukify.py @@ -1859,6 +1859,17 @@ class ConfigItem: args = self._names() parser.add_argument(*args, **kwargs) + def parse_value(self, s: str) -> Any: + if self.action == argparse.BooleanOptionalAction: + # We need to handle this case separately: the options are called + # --foo and --no-foo, and no argument is parsed. But in the config + # file, we have Foo=yes or Foo=no. + return self.parse_boolean(s) + elif self.type: + return self.type(s) + + return s + def apply_config( self, namespace: argparse.Namespace, @@ -1870,24 +1881,13 @@ class ConfigItem: assert f'{section}/{key}' == self.config_key dest = self.argparse_dest() - conv: Callable[[str], Any] - if self.action == argparse.BooleanOptionalAction: - # We need to handle this case separately: the options are called - # --foo and --no-foo, and no argument is parsed. But in the config - # file, we have Foo=yes or Foo=no. - conv = self.parse_boolean - elif self.type: - conv = self.type - else: - conv = lambda s: s - # This is a bit ugly, but --initrd and --devicetree-auto are the only options # with multiple args on the command line and a space-separated list in the # config file. if self.name in ['--initrd', '--devicetree-auto']: - value = [conv(v) for v in value.split()] + value = [self.parse_value(v) for v in value.split()] else: - value = conv(value) + value = self.parse_value(value) self.config_push(namespace, group, dest, value) From f4fcd5cfad769e022e87ad058d66f0b9b6e28753 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Behrmann?= Date: Wed, 25 Feb 2026 10:26:59 +0100 Subject: [PATCH 2/7] hwdb/ids_parser: make text_eol a proper function --- hwdb.d/ids_parser.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hwdb.d/ids_parser.py b/hwdb.d/ids_parser.py index 7efd934f46..d517f6b909 100755 --- a/hwdb.d/ids_parser.py +++ b/hwdb.d/ids_parser.py @@ -31,11 +31,14 @@ NUM6 = Word('0123456789abcdefABCDEF', exact=6) TAB = White('\t', exact=1).suppress() COMMENTLINE = pythonStyleComment + EOL EMPTYLINE = LineEnd() -text_eol = lambda name: Regex(r'[^\n]+')(name) + EOL ParserElement.setDefaultWhitespaceChars(' \n') +def text_eol(name): + return Regex(r'[^\n]+')(name) + EOL + + def klass_grammar(): # fmt: off klass_line = Literal('C ').suppress() + NUM2('klass') + text_eol('text') From 7cf552e4816715f9e2f0784a3dde803500ec66bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Behrmann?= Date: Wed, 25 Feb 2026 10:42:31 +0100 Subject: [PATCH 3/7] test-network: remove unused variable --- test/test-network/systemd-networkd-tests.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 3d3931adec..50a5478eda 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -817,7 +817,6 @@ def stop_by_pid_file(pid_file): def dnr_v4_instance_data(adn, addrs=None, prio=1, alpns=('dot',), dohpath=None): - b = b'' pack = lambda c, w=1: struct.pack('>' + '_BH_I'[w], len(c)) + c pyton = lambda n, w=2: struct.pack('>' + '_BH_I'[w], n) ipv4 = ipaddress.IPv4Address @@ -829,13 +828,13 @@ def dnr_v4_instance_data(adn, addrs=None, prio=1, alpns=('dot',), dohpath=None): data = pyton(prio) adn = adn.rstrip('.') + '.' - data += pack(b.join(pack(label.encode('ascii')) for label in adn.split('.'))) + data += pack(b''.join(pack(label.encode('ascii')) for label in adn.split('.'))) if not addrs: # adn-only mode return pack(data, 2) - data += pack(b.join(ipv4(addr).packed for addr in addrs)) - data += pyton(SvcParam.ALPN.value) + pack(b.join(pack(alpn.encode('ascii')) for alpn in alpns), 2) + data += pack(b''.join(ipv4(addr).packed for addr in addrs)) + data += pyton(SvcParam.ALPN.value) + pack(b''.join(pack(alpn.encode('ascii')) for alpn in alpns), 2) if dohpath is not None: data += pyton(SvcParam.DOHPATH.value) + pack(dohpath.encode('utf-8'), 2) @@ -843,7 +842,6 @@ def dnr_v4_instance_data(adn, addrs=None, prio=1, alpns=('dot',), dohpath=None): def dnr_v6_instance_data(adn, addrs=None, prio=1, alpns=('dot',), dohpath=None): - b = b'' pack = lambda c, w=1: struct.pack('>' + '_BH_I'[w], len(c)) + c pyton = lambda n, w=2: struct.pack('>' + '_BH_I'[w], n) ipv6 = ipaddress.IPv6Address @@ -855,13 +853,13 @@ def dnr_v6_instance_data(adn, addrs=None, prio=1, alpns=('dot',), dohpath=None): data = pyton(prio) adn = adn.rstrip('.') + '.' - data += pack(b.join(pack(label.encode('ascii')) for label in adn.split('.')), 2) + data += pack(b''.join(pack(label.encode('ascii')) for label in adn.split('.')), 2) if not addrs: # adn-only mode return data - data += pack(b.join(ipv6(addr).packed for addr in addrs), 2) - data += pyton(SvcParam.ALPN.value) + pack(b.join(pack(alpn.encode('ascii')) for alpn in alpns), 2) + data += pack(b''.join(ipv6(addr).packed for addr in addrs), 2) + data += pyton(SvcParam.ALPN.value) + pack(b''.join(pack(alpn.encode('ascii')) for alpn in alpns), 2) if dohpath is not None: data += pyton(SvcParam.DOHPATH.value) + pack(dohpath.encode('utf-8'), 2) From 475fb5e44fc3af4fd8b0e7308dceb44670388f8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Behrmann?= Date: Wed, 25 Feb 2026 10:43:08 +0100 Subject: [PATCH 4/7] test-network: factor out common enum --- test/test-network/systemd-networkd-tests.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 50a5478eda..0f816aab83 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -816,15 +816,16 @@ def stop_by_pid_file(pid_file): rm_f(pid_file) +class SvcParam(enum.Enum): + ALPN = 1 + DOHPATH = 7 + + def dnr_v4_instance_data(adn, addrs=None, prio=1, alpns=('dot',), dohpath=None): pack = lambda c, w=1: struct.pack('>' + '_BH_I'[w], len(c)) + c pyton = lambda n, w=2: struct.pack('>' + '_BH_I'[w], n) ipv4 = ipaddress.IPv4Address - class SvcParam(enum.Enum): - ALPN = 1 - DOHPATH = 7 - data = pyton(prio) adn = adn.rstrip('.') + '.' @@ -846,10 +847,6 @@ def dnr_v6_instance_data(adn, addrs=None, prio=1, alpns=('dot',), dohpath=None): pyton = lambda n, w=2: struct.pack('>' + '_BH_I'[w], n) ipv6 = ipaddress.IPv6Address - class SvcParam(enum.Enum): - ALPN = 1 - DOHPATH = 7 - data = pyton(prio) adn = adn.rstrip('.') + '.' From 9ea0b5f68872d1843757ef93c8770bd785c7255c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Behrmann?= Date: Wed, 25 Feb 2026 10:59:04 +0100 Subject: [PATCH 5/7] test-network: factor out common functions --- test/test-network/systemd-networkd-tests.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 0f816aab83..ec01e2a3bc 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -816,14 +816,23 @@ def stop_by_pid_file(pid_file): rm_f(pid_file) +def pack(c, width=1): + # big-endian unsigned char/short/integer + fmt = {1: '>B', 2: '>H', 4: '>I'} + return struct.pack(fmt[width], len(c)) + c + + +def pyton(n, width=2): + fmt = {1: '>B', 2: '>H', 4: '>I'} + return struct.pack(fmt[width], n) + + class SvcParam(enum.Enum): ALPN = 1 DOHPATH = 7 def dnr_v4_instance_data(adn, addrs=None, prio=1, alpns=('dot',), dohpath=None): - pack = lambda c, w=1: struct.pack('>' + '_BH_I'[w], len(c)) + c - pyton = lambda n, w=2: struct.pack('>' + '_BH_I'[w], n) ipv4 = ipaddress.IPv4Address data = pyton(prio) @@ -843,8 +852,6 @@ def dnr_v4_instance_data(adn, addrs=None, prio=1, alpns=('dot',), dohpath=None): def dnr_v6_instance_data(adn, addrs=None, prio=1, alpns=('dot',), dohpath=None): - pack = lambda c, w=1: struct.pack('>' + '_BH_I'[w], len(c)) + c - pyton = lambda n, w=2: struct.pack('>' + '_BH_I'[w], n) ipv6 = ipaddress.IPv6Address data = pyton(prio) From b54d1679341761047c96e5c5a31c0ebad58592f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Behrmann?= Date: Wed, 25 Feb 2026 11:00:54 +0100 Subject: [PATCH 6/7] test-network: make masq a proper function --- test/test-network/systemd-networkd-tests.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index ec01e2a3bc..fabb76fcbf 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -9738,6 +9738,9 @@ Address={ipv6_address} check_json(networkctl_json()) + def masq(bs): + return ':'.join(f'{b:02x}' for b in bs) + copy_network_unit( '25-veth.netdev', '25-dhcp-server-veth-peer.network', @@ -9761,7 +9764,6 @@ Address={ipv6_address} adn='dns.google', addrs=['2001:4860:4860::8888', '2001:4860:4860::8844'], ) - masq = lambda bs: ':'.join(f'{b:02x}' for b in bs) start_dnsmasq(f'--dhcp-option=162,{masq(dnr_v4)}', f'--dhcp-option=option6:144,{masq(dnr_v6)}') check(self, True, True) From 76b5d77cddc4c528a69451e4216c6e51f6454413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Behrmann?= Date: Wed, 25 Feb 2026 11:05:34 +0100 Subject: [PATCH 7/7] ci/linter: stop ignoring lambda assignment lint --- ruff.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ruff.toml b/ruff.toml index c88204d650..0795d9b9de 100644 --- a/ruff.toml +++ b/ruff.toml @@ -7,8 +7,7 @@ extend-exclude = ["tools/chromiumos/gen_autosuspend_rules.py"] [lint] select = ["E", "F", "I", "Q", "UP"] # E501: line-too-long -# E731: lambda-assignment -ignore = ["E501", "E731"] +ignore = ["E501"] [format] # The formatter prefers double quotes for multiline quotes,