style: edtlib: Use a better line continuation operator

Replace backslashes('\') with PEP-8 recommended
parentheses('( )') as the line continuation operator.

Signed-off-by: James Roy <rruuaanng@outlook.com>
This commit is contained in:
James Roy 2024-12-28 21:23:31 +08:00 committed by Benjamin Cabé
parent 67597cf85a
commit 802eac71f0
3 changed files with 85 additions and 82 deletions

View file

@ -411,8 +411,8 @@ def write_interrupts(node: edtlib.Node) -> None:
idx_vals.append((idx_macro, cell_value)) idx_vals.append((idx_macro, cell_value))
idx_vals.append((idx_macro + "_EXISTS", 1)) idx_vals.append((idx_macro + "_EXISTS", 1))
if irq.name: if irq.name:
name_macro = \ name_macro = (
f"{path_id}_IRQ_NAME_{str2ident(irq.name)}_VAL_{name}" f"{path_id}_IRQ_NAME_{str2ident(irq.name)}_VAL_{name}")
name_vals.append((name_macro, f"DT_{idx_macro}")) name_vals.append((name_macro, f"DT_{idx_macro}"))
name_vals.append((name_macro + "_EXISTS", 1)) name_vals.append((name_macro + "_EXISTS", 1))
@ -619,28 +619,27 @@ def write_vanilla_props(node: edtlib.Node) -> None:
plen = prop_len(prop) plen = prop_len(prop)
if plen is not None: if plen is not None:
# DT_N_<node-id>_P_<prop-id>_FOREACH_PROP_ELEM # DT_N_<node-id>_P_<prop-id>_FOREACH_PROP_ELEM
macro2val[f"{macro}_FOREACH_PROP_ELEM(fn)"] = \ macro2val[f"{macro}_FOREACH_PROP_ELEM(fn)"] = (
' \\\n\t'.join( ' \\\n\t'.join(f'fn(DT_{node.z_path_id}, {prop_id}, {i})'
f'fn(DT_{node.z_path_id}, {prop_id}, {i})' for i in range(plen)))
for i in range(plen))
# DT_N_<node-id>_P_<prop-id>_FOREACH_PROP_ELEM_SEP # DT_N_<node-id>_P_<prop-id>_FOREACH_PROP_ELEM_SEP
macro2val[f"{macro}_FOREACH_PROP_ELEM_SEP(fn, sep)"] = \ macro2val[f"{macro}_FOREACH_PROP_ELEM_SEP(fn, sep)"] = (
' DT_DEBRACKET_INTERNAL sep \\\n\t'.join( ' DT_DEBRACKET_INTERNAL sep \\\n\t'.join(
f'fn(DT_{node.z_path_id}, {prop_id}, {i})' f'fn(DT_{node.z_path_id}, {prop_id}, {i})'
for i in range(plen)) for i in range(plen)))
# DT_N_<node-id>_P_<prop-id>_FOREACH_PROP_ELEM_VARGS # DT_N_<node-id>_P_<prop-id>_FOREACH_PROP_ELEM_VARGS
macro2val[f"{macro}_FOREACH_PROP_ELEM_VARGS(fn, ...)"] = \ macro2val[f"{macro}_FOREACH_PROP_ELEM_VARGS(fn, ...)"] = (
' \\\n\t'.join( ' \\\n\t'.join(
f'fn(DT_{node.z_path_id}, {prop_id}, {i}, __VA_ARGS__)' f'fn(DT_{node.z_path_id}, {prop_id}, {i}, __VA_ARGS__)'
for i in range(plen)) for i in range(plen)))
# DT_N_<node-id>_P_<prop-id>_FOREACH_PROP_ELEM_SEP_VARGS # DT_N_<node-id>_P_<prop-id>_FOREACH_PROP_ELEM_SEP_VARGS
macro2val[f"{macro}_FOREACH_PROP_ELEM_SEP_VARGS(fn, sep, ...)"] = \ macro2val[f"{macro}_FOREACH_PROP_ELEM_SEP_VARGS(fn, sep, ...)"] = (
' DT_DEBRACKET_INTERNAL sep \\\n\t'.join( ' DT_DEBRACKET_INTERNAL sep \\\n\t'.join(
f'fn(DT_{node.z_path_id}, {prop_id}, {i}, __VA_ARGS__)' f'fn(DT_{node.z_path_id}, {prop_id}, {i}, __VA_ARGS__)'
for i in range(plen)) for i in range(plen)))
# DT_N_<node-id>_P_<prop-id>_LEN # DT_N_<node-id>_P_<prop-id>_LEN
macro2val[f"{macro}_LEN"] = plen macro2val[f"{macro}_LEN"] = plen
@ -715,9 +714,9 @@ def write_dep_info(node: edtlib.Node) -> None:
if dep_list: if dep_list:
# Sort the list by dependency ordinal for predictability. # Sort the list by dependency ordinal for predictability.
sorted_list = sorted(dep_list, key=lambda node: node.dep_ordinal) sorted_list = sorted(dep_list, key=lambda node: node.dep_ordinal)
return "\\\n\t" + \ return ("\\\n\t" + " \\\n\t"
" \\\n\t".join(f"{n.dep_ordinal}, /* {n.path} */" .join(f"{n.dep_ordinal}, /* {n.path} */"
for n in sorted_list) for n in sorted_list))
else: else:
return "/* nothing */" return "/* nothing */"
@ -867,8 +866,8 @@ def controller_and_data_macros(entry: edtlib.ControllerAndData, i: int, macro: s
# DT_N_<node-id>_P_<prop-id>_NAME_<NAME>_VAL_<VAL> # DT_N_<node-id>_P_<prop-id>_NAME_<NAME>_VAL_<VAL>
for cell, val in data.items(): for cell, val in data.items():
cell_ident = str2ident(cell) cell_ident = str2ident(cell)
ret[f"{macro}_NAME_{name}_VAL_{cell_ident}"] = \ ret[f"{macro}_NAME_{name}_VAL_{cell_ident}"] = (
f"DT_{macro}_IDX_{i}_VAL_{cell_ident}" f"DT_{macro}_IDX_{i}_VAL_{cell_ident}")
ret[f"{macro}_NAME_{name}_VAL_{cell_ident}_EXISTS"] = 1 ret[f"{macro}_NAME_{name}_VAL_{cell_ident}_EXISTS"] = 1
return ret return ret
@ -919,24 +918,24 @@ def write_global_macros(edt: edtlib.EDT):
# Helpers for non-INST for-each macros that take node # Helpers for non-INST for-each macros that take node
# identifiers as arguments. # identifiers as arguments.
for_each_macros[f"DT_FOREACH_OKAY_{ident}(fn)"] = \ for_each_macros[f"DT_FOREACH_OKAY_{ident}(fn)"] = (
" ".join(f"fn(DT_{node.z_path_id})" " ".join(f"fn(DT_{node.z_path_id})"
for node in okay_nodes) for node in okay_nodes))
for_each_macros[f"DT_FOREACH_OKAY_VARGS_{ident}(fn, ...)"] = \ for_each_macros[f"DT_FOREACH_OKAY_VARGS_{ident}(fn, ...)"] = (
" ".join(f"fn(DT_{node.z_path_id}, __VA_ARGS__)" " ".join(f"fn(DT_{node.z_path_id}, __VA_ARGS__)"
for node in okay_nodes) for node in okay_nodes))
# Helpers for INST versions of for-each macros, which take # Helpers for INST versions of for-each macros, which take
# instance numbers. We emit separate helpers for these because # instance numbers. We emit separate helpers for these because
# avoiding an intermediate node_id --> instance number # avoiding an intermediate node_id --> instance number
# conversion in the preprocessor helps to keep the macro # conversion in the preprocessor helps to keep the macro
# expansions simpler. That hopefully eases debugging. # expansions simpler. That hopefully eases debugging.
for_each_macros[f"DT_FOREACH_OKAY_INST_{ident}(fn)"] = \ for_each_macros[f"DT_FOREACH_OKAY_INST_{ident}(fn)"] = (
" ".join(f"fn({edt.compat2nodes[compat].index(node)})" " ".join(f"fn({edt.compat2nodes[compat].index(node)})"
for node in okay_nodes) for node in okay_nodes))
for_each_macros[f"DT_FOREACH_OKAY_INST_VARGS_{ident}(fn, ...)"] = \ for_each_macros[f"DT_FOREACH_OKAY_INST_VARGS_{ident}(fn, ...)"] = (
" ".join(f"fn({edt.compat2nodes[compat].index(node)}, __VA_ARGS__)" " ".join(f"fn({edt.compat2nodes[compat].index(node)}, __VA_ARGS__)"
for node in okay_nodes) for node in okay_nodes))
for compat, nodes in edt.compat2nodes.items(): for compat, nodes in edt.compat2nodes.items():
for node in nodes: for node in nodes:

View file

@ -20,8 +20,9 @@ import re
import string import string
import sys import sys
import textwrap import textwrap
from typing import Any, Dict, Iterable, List, \ from typing import (Any, Dict, Iterable, List,
NamedTuple, NoReturn, Optional, Set, Tuple, TYPE_CHECKING, Union NamedTuple, NoReturn, Optional,
Set, Tuple, TYPE_CHECKING, Union)
# NOTE: tests/test_dtlib.py is the test suite for this library. # NOTE: tests/test_dtlib.py is the test suite for this library.
@ -353,8 +354,8 @@ class Property:
if types == [_MarkerType.PATH]: if types == [_MarkerType.PATH]:
return Type.PATH return Type.PATH
if types == [_MarkerType.UINT32, _MarkerType.PHANDLE] and \ if (types == [_MarkerType.UINT32, _MarkerType.PHANDLE]
len(self.value) == 4: and len(self.value) == 4):
return Type.PHANDLE return Type.PHANDLE
if set(types) == {_MarkerType.UINT32, _MarkerType.PHANDLE}: if set(types) == {_MarkerType.UINT32, _MarkerType.PHANDLE}:
@ -608,9 +609,10 @@ class Property:
pos += elm_size pos += elm_size
if pos != 0 and \ if (pos != 0
(not next_marker or and (not next_marker
next_marker[1] not in (_MarkerType.PHANDLE, _MarkerType.LABEL)): or next_marker[1]
not in (_MarkerType.PHANDLE, _MarkerType.LABEL))):
s += _N_BYTES_TO_END_STR[elm_size] s += _N_BYTES_TO_END_STR[elm_size]
if pos != len(self.value): if pos != len(self.value):
@ -620,8 +622,8 @@ class Property:
def __repr__(self): def __repr__(self):
return f"<Property '{self.name}' at '{self.node.path}' in " \ return (f"<Property '{self.name}' at '{self.node.path}' in "
f"'{self.node.dt.filename}'>" f"'{self.node.dt.filename}'>")
# #
# Internal functions # Internal functions
@ -914,8 +916,8 @@ class DT:
the DT instance is evaluated. the DT instance is evaluated.
""" """
if self.filename: if self.filename:
return f"DT(filename='{self.filename}', " \ return (f"DT(filename='{self.filename}', "
f"include_path={self._include_path})" f"include_path={self._include_path})")
return super().__repr__() return super().__repr__()
def __deepcopy__(self, memo): def __deepcopy__(self, memo):
@ -1634,8 +1636,8 @@ class DT:
# State handling # State handling
if tok_id in (_T.DEL_PROP, _T.DEL_NODE, _T.OMIT_IF_NO_REF) or \ if (tok_id in (_T.DEL_PROP, _T.DEL_NODE, _T.OMIT_IF_NO_REF)
tok_val in ("{", ";"): or tok_val in ("{", ";")):
self._lexer_state = _EXPECT_PROPNODENAME self._lexer_state = _EXPECT_PROPNODENAME
@ -1709,8 +1711,8 @@ class DT:
def _leave_file(self): def _leave_file(self):
# Leaves an /include/d file, returning to the file that /include/d it # Leaves an /include/d file, returning to the file that /include/d it
self.filename, self._lineno, self._file_contents, self._tok_end_i = \ self.filename, self._lineno, self._file_contents, self._tok_end_i = (
self._filestack.pop() self._filestack.pop())
def _next_ref2node(self): def _next_ref2node(self):
# Checks that the next token is a label/path reference and returns the # Checks that the next token is a label/path reference and returns the
@ -2067,10 +2069,10 @@ def _decode_and_escape(b):
# 'backslashreplace' bytes.translate() can't map to more than a single # 'backslashreplace' bytes.translate() can't map to more than a single
# byte, but str.translate() can map to more than one character, so it's # byte, but str.translate() can map to more than one character, so it's
# nice here. There's probably a nicer way to do this. # nice here. There's probably a nicer way to do this.
return b.decode("utf-8", "surrogateescape") \ return (b.decode("utf-8", "surrogateescape")
.translate(_escape_table) \ .translate(_escape_table)
.encode("utf-8", "surrogateescape") \ .encode("utf-8", "surrogateescape")
.decode("utf-8", "backslashreplace") .decode("utf-8", "backslashreplace"))
def _root_and_path_to_node(cur, path, fullpath): def _root_and_path_to_node(cur, path, fullpath):
# Returns the node pointed at by 'path', relative to the Node 'cur'. For # Returns the node pointed at by 'path', relative to the Node 'cur'. For

View file

@ -70,8 +70,8 @@ bindings_from_paths() helper function.
from collections import defaultdict from collections import defaultdict
from copy import deepcopy from copy import deepcopy
from dataclasses import dataclass from dataclasses import dataclass
from typing import Any, Callable, Dict, Iterable, List, NoReturn, \ from typing import (Any, Callable, Dict, Iterable, List, NoReturn,
Optional, Set, TYPE_CHECKING, Tuple, Union Optional, Set, TYPE_CHECKING, Tuple, Union)
import logging import logging
import os import os
import re import re
@ -401,9 +401,9 @@ class Binding:
if "bus" in raw: if "bus" in raw:
bus = raw["bus"] bus = raw["bus"]
if not isinstance(bus, str) and \ if (not isinstance(bus, str) and
(not isinstance(bus, list) and \ (not isinstance(bus, list) and
not all(isinstance(elem, str) for elem in bus)): not all(isinstance(elem, str) for elem in bus))):
_err(f"malformed 'bus:' value in {self.path}, " _err(f"malformed 'bus:' value in {self.path}, "
"expected string or list of strings") "expected string or list of strings")
@ -413,8 +413,8 @@ class Binding:
# Convert bus into a list # Convert bus into a list
self._buses = [bus] self._buses = [bus]
if "on-bus" in raw and \ if ("on-bus" in raw
not isinstance(raw["on-bus"], str): and not isinstance(raw["on-bus"], str)):
_err(f"malformed 'on-bus:' value in {self.path}, " _err(f"malformed 'on-bus:' value in {self.path}, "
"expected string") "expected string")
@ -422,8 +422,8 @@ class Binding:
for key, val in raw.items(): for key, val in raw.items():
if key.endswith("-cells"): if key.endswith("-cells"):
if not isinstance(val, list) or \ if (not isinstance(val, list)
not all(isinstance(elem, str) for elem in val): or not all(isinstance(elem, str) for elem in val)):
_err(f"malformed '{key}:' in {self.path}, " _err(f"malformed '{key}:' in {self.path}, "
"expected a list of strings") "expected a list of strings")
@ -460,8 +460,8 @@ class Binding:
_err(f"'{prop_name}' in 'properties' in {self.path} should not " _err(f"'{prop_name}' in 'properties' in {self.path} should not "
"have both 'deprecated' and 'required' set") "have both 'deprecated' and 'required' set")
if "description" in options and \ if ("description" in options
not isinstance(options["description"], str): and not isinstance(options["description"], str)):
_err("missing, malformed, or empty 'description' for " _err("missing, malformed, or empty 'description' for "
f"'{prop_name}' in 'properties' in {self.path}") f"'{prop_name}' in 'properties' in {self.path}")
@ -579,9 +579,10 @@ class PropertySpec:
if not self.enum_tokenizable: if not self.enum_tokenizable:
self._enum_upper_tokenizable = False self._enum_upper_tokenizable = False
else: else:
self._enum_upper_tokenizable = \ self._enum_upper_tokenizable = (
(len(self._as_tokens) == len(self._as_tokens) == len(
len(set(x.upper() for x in self._as_tokens))) set(x.upper() for x in self._as_tokens)
))
return self._enum_upper_tokenizable return self._enum_upper_tokenizable
@property @property
@ -1585,14 +1586,14 @@ class Node:
def _check_undeclared_props(self) -> None: def _check_undeclared_props(self) -> None:
# Checks that all properties are declared in the binding # Checks that all properties are declared in the binding
wl = {"compatible", "status", "ranges", "phandle",
"interrupt-parent", "interrupts-extended", "device_type"}
for prop_name in self._node.props: for prop_name in self._node.props:
# Allow a few special properties to not be declared in the binding # Allow a few special properties to not be declared in the binding
if prop_name.endswith("-controller") or \ if (prop_name.endswith("-controller")
prop_name.startswith("#") or \ or prop_name.startswith("#")
prop_name in { or prop_name in wl):
"compatible", "status", "ranges", "phandle",
"interrupt-parent", "interrupts-extended", "device_type"}:
continue continue
if TYPE_CHECKING: if TYPE_CHECKING:
@ -1807,9 +1808,9 @@ class Node:
continue continue
controller_node, data = item controller_node, data = item
mapped_controller, mapped_data = \ mapped_controller, mapped_data = (
_map_phandle_array_entry(prop.node, controller_node, data, _map_phandle_array_entry(prop.node, controller_node,
specifier_space) data, specifier_space))
controller = self.edt._node2enode[mapped_controller] controller = self.edt._node2enode[mapped_controller]
# We'll fix up the names below. # We'll fix up the names below.
@ -2066,8 +2067,8 @@ class EDT:
return f"{self._dt}" return f"{self._dt}"
def __repr__(self) -> str: def __repr__(self) -> str:
return f"<EDT for '{self.dts_path}', binding directories " \ return (f"<EDT for '{self.dts_path}', binding directories "
f"'{self.bindings_dirs}'>" f"'{self.bindings_dirs}'>")
def __deepcopy__(self, memo) -> 'EDT': def __deepcopy__(self, memo) -> 'EDT':
""" """
@ -2493,12 +2494,12 @@ def _check_include_dict(name: Optional[str],
while child_filter is not None: while child_filter is not None:
child_copy = deepcopy(child_filter) child_copy = deepcopy(child_filter)
child_allowlist: Optional[List[str]] = \ child_allowlist: Optional[List[str]] = (
child_copy.pop('property-allowlist', None) child_copy.pop('property-allowlist', None))
child_blocklist: Optional[List[str]] = \ child_blocklist: Optional[List[str]] = (
child_copy.pop('property-blocklist', None) child_copy.pop('property-blocklist', None))
next_child_filter: Optional[dict] = \ next_child_filter: Optional[dict] = (
child_copy.pop('child-binding', None) child_copy.pop('child-binding', None))
if child_copy: if child_copy:
# We've popped out all the valid keys. # We've popped out all the valid keys.
@ -2595,8 +2596,8 @@ def _merge_props(to_dict: dict,
# These are used to generate errors for sketchy property overwrites. # These are used to generate errors for sketchy property overwrites.
for prop in from_dict: for prop in from_dict:
if isinstance(to_dict.get(prop), dict) and \ if (isinstance(to_dict.get(prop), dict)
isinstance(from_dict[prop], dict): and isinstance(from_dict[prop], dict)):
_merge_props(to_dict[prop], from_dict[prop], prop, binding_path, _merge_props(to_dict[prop], from_dict[prop], prop, binding_path,
check_required) check_required)
elif prop not in to_dict: elif prop not in to_dict:
@ -2709,8 +2710,8 @@ def _check_prop_by_type(prop_name: str,
# If you change this, be sure to update the type annotation for # If you change this, be sure to update the type annotation for
# PropertySpec.default. # PropertySpec.default.
if prop_type == "int" and isinstance(default, int) or \ if (prop_type == "int" and isinstance(default, int)
prop_type == "string" and isinstance(default, str): or prop_type == "string" and isinstance(default, str)):
return True return True
# array, uint8-array, or string-array # array, uint8-array, or string-array
@ -2718,12 +2719,13 @@ def _check_prop_by_type(prop_name: str,
if not isinstance(default, list): if not isinstance(default, list):
return False return False
if prop_type == "array" and \ if (prop_type == "array"
all(isinstance(val, int) for val in default): and all(isinstance(val, int) for val in default)):
return True return True
if prop_type == "uint8-array" and \ if (prop_type == "uint8-array"
all(isinstance(val, int) and 0 <= val <= 255 for val in default): and all(isinstance(val, int)
and 0 <= val <= 255 for val in default)):
return True return True
# string-array # string-array