[lint] add PERF401 lint (#12070)

Co-authored-by: daniel.eades <daniel.eades@seebyte.com>
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
This commit is contained in:
danieleades
2024-03-14 10:16:36 +00:00
committed by GitHub
parent fb91cb3f43
commit d4c739cdd1
14 changed files with 60 additions and 83 deletions

View File

@@ -186,7 +186,7 @@ select = [
"PERF101", # Do not cast an iterable to `list` before iterating over it
"PERF102", # When using only the {subset} of a dict use the `{subset}()` method
# "PERF203", # `try`-`except` within a loop incurs performance overhead
# "PERF401", # Use a list comprehension to create a transformed list
"PERF401", # Use a list comprehension to create a transformed list
"PERF402", # Use `list` or `list.copy` to create a copy of a list
"PERF403", # Use a dictionary comprehension instead of a for-loop
# pygrep-hooks ('PGH')

View File

@@ -349,10 +349,7 @@ class ASTPostfixExpr(ASTExpression):
self.postFixes = postFixes
def _stringify(self, transform: StringifyTransform) -> str:
res = [transform(self.prefix)]
for p in self.postFixes:
res.append(transform(p))
return ''.join(res)
return ''.join([transform(self.prefix), *(transform(p) for p in self.postFixes)])
def describe_signature(self, signode: TextElement, mode: str,
env: BuildEnvironment, symbol: Symbol) -> None:
@@ -881,8 +878,7 @@ class ASTDeclaratorNameParam(ASTDeclarator):
res = []
if self.declId:
res.append(transform(self.declId))
for op in self.arrayOps:
res.append(transform(op))
res.extend(transform(op) for op in self.arrayOps)
if self.param:
res.append(transform(self.param))
return ''.join(res)

View File

@@ -693,7 +693,4 @@ class Symbol:
return ''.join(res)
def dump(self, indent: int) -> str:
res = [self.to_string(indent)]
for c in self._children:
res.append(c.dump(indent + 1))
return ''.join(res)
return ''.join([self.to_string(indent), *(c.dump(indent + 1) for c in self._children)])

View File

@@ -194,8 +194,7 @@ class ASTNestedName(ASTBase):
if len(self.names) > 1 or len(modifiers) > 0:
res.append('N')
res.append(modifiers)
for n in self.names:
res.append(n.get_id(version))
res.extend(n.get_id(version) for n in self.names)
if len(self.names) > 1 or len(modifiers) > 0:
res.append('E')
return ''.join(res)
@@ -631,11 +630,12 @@ class ASTPostfixCallExpr(ASTPostfixOp):
return transform(self.lst)
def get_id(self, idPrefix: str, version: int) -> str:
res = ['cl', idPrefix]
for e in self.lst.exprs:
res.append(e.get_id(version))
res.append('E')
return ''.join(res)
return ''.join([
'cl',
idPrefix,
*(e.get_id(version) for e in self.lst.exprs),
'E',
])
def describe_signature(self, signode: TextElement, mode: str,
env: BuildEnvironment, symbol: Symbol) -> None:
@@ -648,10 +648,7 @@ class ASTPostfixExpr(ASTExpression):
self.postFixes = postFixes
def _stringify(self, transform: StringifyTransform) -> str:
res = [transform(self.prefix)]
for p in self.postFixes:
res.append(transform(p))
return ''.join(res)
return ''.join([transform(self.prefix), *(transform(p) for p in self.postFixes)])
def get_id(self, version: int) -> str:
id = self.prefix.get_id(version)
@@ -2019,8 +2016,7 @@ class ASTDeclaratorNameParamQual(ASTDeclarator):
res = []
if self.declId:
res.append(transform(self.declId))
for op in self.arrayOps:
res.append(transform(op))
res.extend(transform(op) for op in self.arrayOps)
if self.paramQual:
res.append(transform(self.paramQual))
return ''.join(res)
@@ -3229,13 +3225,10 @@ class ASTTemplateParams(ASTBase):
assert version >= 2
res = []
res.append("I")
for param in self.params:
res.append(param.get_id(version))
res.extend(param.get_id(version) for param in self.params)
res.append("E")
if not excludeRequires and self.requiresClause:
res.append('IQ')
res.append(self.requiresClause.expr.get_id(version))
res.append('E')
res.extend(['IQ', self.requiresClause.expr.get_id(version), 'E'])
return ''.join(res)
def _stringify(self, transform: StringifyTransform) -> str:
@@ -3360,21 +3353,19 @@ class ASTTemplateIntroduction(ASTBase):
def get_id(self, version: int) -> str:
assert version >= 2
# first do the same as a normal template parameter list
res = []
res.append("I")
for param in self.params:
res.append(param.get_id(version))
res.append("E")
# let's use X expr E, which is otherwise for constant template args
res.append("X")
res.append(self.concept.get_id(version))
res.append("I")
for param in self.params:
res.append(param.get_id_as_arg(version))
res.append("E")
res.append("E")
return ''.join(res)
return ''.join([
# first do the same as a normal template parameter list
"I",
*(param.get_id(version) for param in self.params),
"E",
# let's use X expr E, which is otherwise for constant template args
"X",
self.concept.get_id(version),
"I",
*(param.get_id_as_arg(version) for param in self.params),
"E",
"E",
])
def _stringify(self, transform: StringifyTransform) -> str:
res = []

View File

@@ -1086,7 +1086,7 @@ class Symbol:
return ''.join(res)
def dump(self, indent: int) -> str:
res = [self.to_string(indent)]
for c in self._children:
res.append(c.dump(indent + 1))
return ''.join(res)
return ''.join([
self.to_string(indent),
*(c.dump(indent + 1) for c in self._children),
])

View File

@@ -73,9 +73,8 @@ def global_toctree_for_doc(
This gives the global ToC, with all ancestors and their siblings.
"""
toctrees: list[Element] = []
for toctree_node in env.master_doctree.findall(addnodes.toctree):
if toctree := _resolve_toctree(
resolved = (
_resolve_toctree(
env,
docname,
builder,
@@ -85,8 +84,13 @@ def global_toctree_for_doc(
titles_only=titles_only,
collapse=collapse,
includehidden=includehidden,
):
toctrees.append(toctree)
)
for toctree_node in env.master_doctree.findall(addnodes.toctree)
)
toctrees = [
toctree for toctree in resolved if toctree is not None
]
if not toctrees:
return None
result = toctrees[0]

View File

@@ -316,20 +316,19 @@ class InheritanceGraph:
# Write the node
this_node_attrs = n_attrs.copy()
if fullname in urls:
this_node_attrs['URL'] = '"%s"' % urls[fullname]
this_node_attrs['target'] = '"_top"'
this_node_attrs["URL"] = '"%s"' % urls[fullname]
this_node_attrs["target"] = '"_top"'
if tooltip:
this_node_attrs['tooltip'] = tooltip
res.append(' "%s" [%s];\n' %
(name, self._format_node_attrs(this_node_attrs)))
this_node_attrs["tooltip"] = tooltip
res.append(' "%s" [%s];\n' % (name, self._format_node_attrs(this_node_attrs)))
# Write the edges
for base_name in bases:
res.append(' "%s" -> "%s" [%s];\n' %
(base_name, name,
self._format_node_attrs(e_attrs)))
res.append('}\n')
return ''.join(res)
res.extend(
' "%s" -> "%s" [%s];\n' % (base_name, name, self._format_node_attrs(e_attrs))
for base_name in bases
)
res.append("}\n")
return "".join(res)
class inheritance_diagram(graphviz):

View File

@@ -313,12 +313,11 @@ class GoogleDocstring:
def _consume_fields(self, parse_type: bool = True, prefer_type: bool = False,
multiple: bool = False) -> list[tuple[str, str, list[str]]]:
self._consume_empty()
fields = []
fields: list[tuple[str, str, list[str]]] = []
while not self._is_section_break():
_name, _type, _desc = self._consume_field(parse_type, prefer_type)
if multiple and _name:
for name in _name.split(","):
fields.append((name.strip(), _type, _desc))
fields.extend((name.strip(), _type, _desc) for name in _name.split(","))
elif _name or _type or _desc:
fields.append((_name, _type, _desc))
return fields

View File

@@ -302,8 +302,7 @@ class BaseParser:
'Invalid %s declaration: %s [error at %d]\n %s\n %s' %
(self.language, msg, self.pos, self.definition, indicator))
errors.append((exMain, "Main error"))
for err in self.otherErrors:
errors.append((err, "Potential other error"))
errors.extend((err, "Potential other error") for err in self.otherErrors)
self.otherErrors = []
raise self._make_multi_error(errors, '')

View File

@@ -54,8 +54,7 @@ def wrap_displaymath(text: str, label: str | None, numbering: bool) -> str:
else:
begin = r'\begin{align*}%s\!\begin{aligned}' % labeldef
end = r'\end{aligned}\end{align*}'
for part in parts:
equations.append('%s\\\\\n' % part.strip())
equations.extend('%s\\\\\n' % part.strip() for part in parts)
concatenated_equations = ''.join(equations)
return f'{begin}\n{concatenated_equations}{end}'

View File

@@ -589,10 +589,8 @@ class HTML5Translator(SphinxTranslator, BaseTranslator):
def visit_productionlist(self, node: Element) -> None:
self.body.append(self.starttag(node, 'pre'))
names = []
productionlist = cast(Iterable[addnodes.production], node)
for production in productionlist:
names.append(production['tokenname'])
names = (production['tokenname'] for production in productionlist)
maxlen = max(len(name) for name in names)
lastname = None
for production in productionlist:

View File

@@ -272,12 +272,10 @@ class ManualPageTranslator(SphinxTranslator, BaseTranslator):
def visit_productionlist(self, node: Element) -> None:
self.ensure_eol()
names = []
self.in_productionlist += 1
self.body.append('.sp\n.nf\n')
productionlist = cast(Iterable[addnodes.production], node)
for production in productionlist:
names.append(production['tokenname'])
names = (production['tokenname'] for production in productionlist)
maxlen = max(len(name) for name in names)
lastname = None
for production in productionlist:

View File

@@ -1291,11 +1291,10 @@ class TexinfoTranslator(SphinxTranslator):
def visit_productionlist(self, node: Element) -> None:
self.visit_literal_block(None)
names = []
productionlist = cast(Iterable[addnodes.production], node)
for production in productionlist:
names.append(production['tokenname'])
names = (production['tokenname'] for production in productionlist)
maxlen = max(len(name) for name in names)
for production in productionlist:
if production['tokenname']:
for id in production.get('ids'):

View File

@@ -749,10 +749,8 @@ class TextTranslator(SphinxTranslator):
def visit_productionlist(self, node: Element) -> None:
self.new_state()
names = []
productionlist = cast(Iterable[addnodes.production], node)
for production in productionlist:
names.append(production['tokenname'])
names = (production['tokenname'] for production in productionlist)
maxlen = max(len(name) for name in names)
lastname = None
for production in productionlist: