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') 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, 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) diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 3d3931adec..fabb76fcbf 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -816,26 +816,35 @@ def stop_by_pid_file(pid_file): rm_f(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 +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 - class SvcParam(enum.Enum): - ALPN = 1 - DOHPATH = 7 + +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): + ipv4 = ipaddress.IPv4Address 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,25 +852,18 @@ 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 - class SvcParam(enum.Enum): - ALPN = 1 - DOHPATH = 7 - 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) @@ -9736,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', @@ -9759,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)