diff --git a/pyproject.toml b/pyproject.toml index b087a8a..108ef31 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,6 +64,18 @@ include = ["src/liblet/*.py", "src/*.py"] sources = ["."] include = ["src/", "docs/"] +[tool.ruff] +indent-width = 2 + +[tool.ruff.lint] +ignore = ["E501", "E731", "EM101", "EM102", "FBT002", "INP001", "N802", "N803", "N806", "SLF001", "TRY003"] + +[tool.ruff.lint.extend-per-file-ignores] +"src/tests/**" = ["ARG001", "E501", "F841", "N802", "PT009", "PT027", "RUF001"] + +[tool.ruff.format] +quote-style = "single" + [tool.hatch.envs.devel] dependencies = ["gitchangelog", "pyupgrade"] diff --git a/src/liblet/antlr.py b/src/liblet/antlr.py index ebb91e5..37bf407 100644 --- a/src/liblet/antlr.py +++ b/src/liblet/antlr.py @@ -156,7 +156,7 @@ def context( parser.setTrace(trace) if diag: parser.addErrorListener(DiagnosticErrorListener()) - parser._interp.predictionMode = PredictionMode.LL_EXACT_AMBIG_DETECTION # noqa: SLF001 + parser._interp.predictionMode = PredictionMode.LL_EXACT_AMBIG_DETECTION parser.buildParseTrees = build_parse_trees if antlr_hook is not None: antlr_hook(lexer, parser) diff --git a/src/liblet/display.py b/src/liblet/display.py index 5913c12..86d2545 100644 --- a/src/liblet/display.py +++ b/src/liblet/display.py @@ -1,10 +1,10 @@ import ast from abc import ABC, abstractmethod from collections import OrderedDict -from collections.abc import Mapping, Set +from collections.abc import Mapping, Set # noqa: PYI025 from functools import partial from html import escape -from itertools import chain +from itertools import chain, pairwise from re import sub from warnings import warn as wwarn @@ -63,7 +63,7 @@ def mapping_aware_gv_args(obj): raise ValueError('node_eq must be either "obj", "str" or a callable') if not callable(default_gv_args): - raise ValueError('default_gv_args must be a callable') + raise TypeError('default_gv_args must be a callable') class NodeWrapper: def __init__(self, obj): @@ -105,9 +105,8 @@ def _obj2wn(self, obj): wn._gid = f'N{len(self.wn2gid)}' self.wn2gid[wn] = wn._gid return (wn, True) - else: - wn._gid = self.wn2gid[wn] - return (wn, False) + wn._gid = self.wn2gid[wn] + return (wn, False) def subgraph(self, **args): return self.G.subgraph(**args) @@ -139,7 +138,7 @@ def _gvgraph_(self): # letstr(node) is always used as node_label # node_id is str(x) where x is id (if not None) or hash(node_label) - def node(self, G, node, id=None, sep=None, gv_args=None): + def node(self, G, node, id=None, sep=None, gv_args=None): # noqa: A002 wwarn('The method "node" is deprecated, use GVWrapper instead of BaseGraph', DeprecationWarning, stacklevel=2) if gv_args is None: gv_args = {} @@ -205,7 +204,7 @@ def __init__(self, root, children=None): self.attr = AttrDict(root) def __iter__(self): - return iter([self.root] + self.children) + return iter([self.root * self.children]) @classmethod def from_lol(cls, lol): @@ -244,7 +243,7 @@ def walk(T): def _gv_graph_(self): G = GVWrapper( - dict( + dict( # noqa: C408 graph_attr={'nodesep': '.25', 'ranksep': '.25'}, node_attr={'shape': 'box', 'width': '0', 'height': '0', 'style': 'rounded, setlinewidth(.25)'}, edge_attr={'dir': 'none'}, @@ -258,7 +257,7 @@ def walk(T): G.edge(curr, (child.root, child)) if len(T.children) > 1: with G.subgraph(edge_attr={'style': 'invis'}, graph_attr={'rank': 'same'}) as S: - for f, t in zip(T.children, T.children[1:]): + for f, t in pairwise(T.children): G.edge((f.root, f), (t.root, t), S) for child in T.children: walk(child) @@ -311,10 +310,10 @@ def with_threads(self, threads): class Graph: def __init__(self, arcs, sep=None): self.G = GVWrapper( - dict(graph_attr={'size': '8', 'rankdir': 'LR'}, node_attr={'shape': 'oval'}), + dict(graph_attr={'size': '8', 'rankdir': 'LR'}, node_attr={'shape': 'oval'}), # noqa: C408 make_node_wrapper(other_str=partial(letstr, sep=sep)), ) - self.adj = dict() + self.adj = {} for src, dst in arcs: self.adj[src] = self.adj.get(src, set()) | {dst} self.adj[dst] = self.adj.get(dst, set()) @@ -348,7 +347,7 @@ class ProductionGraph: def __init__(self, derivation, compact=None): self.derivation = derivation if compact is None: - self.compact = True if derivation.G.is_context_free else False + self.compact = derivation.G.is_context_free else: self.compact = compact self.G = None @@ -361,7 +360,7 @@ def _gv_graph_(self): return self.G derivation = self.derivation G = GVWrapper( - dict( + dict( # noqa: C408 graph_attr={'nodesep': '.25', 'ranksep': '.25'}, node_attr={ 'shape': 'box', @@ -412,7 +411,7 @@ def remove_ε(sentence): gv_args={'style': 'rounded, setlinewidth(1.25)' if node in last_sentence else 'rounded, setlinewidth(.25)'}, ) - for f, t in zip(rhsn, rhsn[1:]): + for f, t in pairwise(rhsn): G.edge(f, t, S) if len(lhs) == 1: @@ -495,7 +494,7 @@ def _gv_graph_(self): return self.G sep = '\n' if self.large_labels else None G = GVWrapper( - dict( + dict( # noqa: C408 graph_attr={'rankdir': 'LR', 'size': '32'}, node_attr={'margin': '.05'} if self.large_labels else {}, engine='dot', @@ -519,10 +518,8 @@ def _gv_graph_(self): def pyast2tree(node): - if not isinstance(node, ast.AST): - return Tree({'type': 'token', 'value': node}) - else: - return Tree( + return ( + Tree( {'type': 'ast', 'name': node.__class__.__name__}, [ Tree(name, [pyast2tree(v) for v in (value if isinstance(value, list) else [value])]) @@ -530,6 +527,9 @@ def pyast2tree(node): if name not in {'type_ignores', 'type_comment'} ], ) + if isinstance(node, ast.AST) + else Tree({'type': 'token', 'value': node}) + ) # Jupyter Widgets sfuff @@ -546,7 +546,7 @@ def animate_derivation(d, height='300px'): # HTML stuff -def __bordered_table__(content): +def __bordered_table__(content): # noqa: N807 return HTML('' + content + '
')