diff --git a/Makefile b/Makefile index fa6a9c3d..7a9d628f 100644 --- a/Makefile +++ b/Makefile @@ -26,12 +26,12 @@ lint: ruff mypy ruff: - pip install -q -U ruff + -@ pip install -q -U ruff ruff check --preview tatsu test examples mypy: - pip install -q -U mypy + -@ pip install -q -U mypy mypy --ignore-missing-imports . --exclude dist diff --git a/examples/calc/calc.py b/examples/calc/calc.py index 658fde8e..8feb4c94 100644 --- a/examples/calc/calc.py +++ b/examples/calc/calc.py @@ -1,4 +1,5 @@ import json +from pathlib import Path from pprint import pprint from codegen import PostfixCodeGenerator @@ -9,7 +10,7 @@ def simple_parse(): - grammar = open('grammars/calc_cut.ebnf').read() + grammar = Path('grammars/calc_cut.ebnf').read_text() parser = tatsu.compile(grammar) ast = parser.parse('3 + 5 * ( 10 - 20 )', trace=False, colorize=True) @@ -26,7 +27,7 @@ def simple_parse(): def annotated_parse(): - grammar = open('grammars/calc_annotated.ebnf').read() + grammar = Path('grammars/calc_annotated.ebnf').read_text() parser = tatsu.compile(grammar) ast = parser.parse('3 + 5 * ( 10 - 20 )') @@ -63,7 +64,7 @@ def expression(self, ast): def parse_with_basic_semantics(): - grammar = open('grammars/calc_annotated.ebnf').read() + grammar = Path('grammars/calc_annotated.ebnf').read_text() parser = tatsu.compile(grammar) result = parser.parse( @@ -95,7 +96,7 @@ def division(self, ast): def parse_factored(): - grammar = open('grammars/calc_factored.ebnf').read() + grammar = Path('grammars/calc_factored.ebnf').read_text() parser = tatsu.compile(grammar) ast = parser.parse('3 + 5 * ( 10 - 20 )', semantics=CalcSemantics()) @@ -107,7 +108,7 @@ def parse_factored(): def parse_to_model(): - grammar = open('grammars/calc_model.ebnf').read() + grammar = Path('grammars/calc_model.ebnf').read_text() parser = tatsu.compile(grammar, asmodel=True) model = parser.parse('3 + 5 * ( 10 - 20 )') @@ -136,7 +137,7 @@ def walk__divide(self, node): def parse_and_walk_model(): - grammar = open('grammars/calc_model.ebnf').read() + grammar = Path('grammars/calc_model.ebnf').read_text() parser = tatsu.compile(grammar, asmodel=True) model = parser.parse('3 + 5 * ( 10 - 20 )') @@ -150,7 +151,7 @@ def parse_and_walk_model(): def parse_and_translate(): - grammar = open('grammars/calc_model.ebnf').read() + grammar = Path('grammars/calc_model.ebnf').read_text() parser = tatsu.compile(grammar, asmodel=True) model = parser.parse('3 + 5 * ( 10 - 20 )') diff --git a/ruff.toml b/ruff.toml index 995519d1..04687d63 100644 --- a/ruff.toml +++ b/ruff.toml @@ -1,30 +1,44 @@ line-length = 88 select = [ - 'F', 'E', 'W', 'UP', - 'I', 'YTT', 'S', 'B', - 'COM', 'C4', 'SIM', - 'PTH', 'TRY', - 'FLY', 'PERF', 'FURB', 'RUF', - 'PL', 'PGH', 'RET', - # 'ERA', # commented out code + "F", "E", "W", "UP", + "I", "YTT", "S", "B", + "COM", "C4", "SIM", + "PTH", "TRY", + "FLY", "PERF", "FURB", "RUF", + "PL", "PGH", "RET", + # "ERA", # commented out code ] ignore = [ - 'E501', 'E741', 'E402', - 'S101', 'S102', 'S105', 'S301', 'S311', - 'C408', - 'SIM115', 'SIM114', - 'PTH123', - 'TRY003', 'TRY300', - 'PLW1514', 'PLR6301', - 'PLC0415', - 'PLR0913', 'PLR2004', 'PLR0904', 'PLR0915', - 'PLW0603', 'PLW2901', 'PLW3201', - 'RET505', +# "C408", # unnecessary-collection-call + "E501", # line-too-long + "E741", # ambiguous-variable-name + "E402", # module-import-not-at-top-of-file + "S101", # use of assert + "PLC0415", # import-outside-top-level + "PLR6301", # no-self-use + "PLR0904", # too-many-public-methods + "PLR0913", # too-many-arguments + "PLR0915", # too-many-statements + "PLR2004", # magic-value-comparison + "PLW1514", # unspecified-encoding +# "PLW0603", # global-statement +# "PLW2901", # redefined-loop-name + "PLW3201", # bad-dunder-method-name +# "PTH123", # builtin-open + "RET505", # superfluous-else-return + "S102", # exec-builtin +# "S105", # hardcoded-password-string + "S301", # suspicious-pickle-usage +# "S311", # suspicious-non-cryptographic-random-usage + "SIM115", # open-file-with-context-handler + "SIM114", # if-with-same-arms + "TRY003", # raise-vanilla-args + "TRY300", # try-consider-else ] -exclude = ['tatsu/bootstrap.py'] +exclude = [] -target-version = 'py312' +target-version = "py312" [per-file-ignores] @@ -33,4 +47,4 @@ target-version = 'py312' max-complexity = 10 [pydocstyle] -convention = 'numpy' +convention = "numpy" diff --git a/tatsu/ast.py b/tatsu/ast.py index d3c550be..4adef9ab 100644 --- a/tatsu/ast.py +++ b/tatsu/ast.py @@ -107,13 +107,11 @@ def _safekey(self, key): return key def _define(self, keys, list_keys=None): - for key in keys: - key = self._safekey(key) + for key in (self._safekey(k) for k in keys): if key not in self: super().__setitem__(key, None) - for key in list_keys or []: - key = self._safekey(key) + for key in (self._safekey(k) for k in list_keys or []): if key not in self: super().__setitem__(key, []) diff --git a/tatsu/bootstrap.py b/tatsu/bootstrap.py index f71ee807..06a21f15 100644 --- a/tatsu/bootstrap.py +++ b/tatsu/bootstrap.py @@ -9,23 +9,24 @@ # Any changes you make to it will be overwritten the next time # the file is generated. +# ruff: noqa: I001, SIM117 + import sys +from pathlib import Path from tatsu.buffering import Buffer from tatsu.parsing import Parser from tatsu.parsing import tatsumasu -from tatsu.parsing import leftrec, nomemo, isname # noqa +from tatsu.parsing import leftrec, nomemo, isname # noqa: F401 from tatsu.infos import ParserConfig -from tatsu.util import re, generic_main # noqa +from tatsu.util import re, generic_main # noqa: F401 -KEYWORDS = {'None'} # type: ignore +KEYWORDS: set[str] = set() class EBNFBootstrapBuffer(Buffer): - def __init__( - self, text, /, config: ParserConfig | None = None, **settings - ): + def __init__(self, text, /, config: ParserConfig | None = None, **settings): config = ParserConfig.new( config, owner=self, @@ -62,11 +63,11 @@ def __init__(self, /, config: ParserConfig | None = None, **settings): super().__init__(config=config) @tatsumasu() - def _start_(self): # noqa + def _start_(self): self._grammar_() @tatsumasu('Grammar') - def _grammar_(self): # noqa + def _grammar_(self): self._constant('TATSU') self.name_last_node('title') @@ -78,8 +79,10 @@ def block1(): with self._option(): self._keyword_() self.add_last_node_to_name('keywords') - self._error('expecting one of: ' ' ') - + self._error( + 'expecting one of: ' + ' ' # noqa: COM812 + ) self._closure(block1) self._rule_() self.add_last_node_to_name('rules') @@ -92,15 +95,20 @@ def block6(): with self._option(): self._keyword_() self.add_last_node_to_name('keywords') - self._error('expecting one of: ' ' ') - + self._error( + 'expecting one of: ' + ' ' # noqa: COM812 + ) self._closure(block6) self._check_eof() - self._define(['title'], ['directives', 'keywords', 'rules']) + self._define( + ['title'], + ['directives', 'keywords', 'rules'], + ) @tatsumasu() - def _directive_(self): # noqa + def _directive_(self): self._token('@@') with self._ifnot(): self._token('keyword') @@ -116,7 +124,7 @@ def _directive_(self): # noqa self._token('eol_comments') self._error( 'expecting one of: ' - "'comments' 'eol_comments'" + "'comments' 'eol_comments'" # noqa: COM812 ) self.name_last_node('name') self._cut() @@ -126,7 +134,10 @@ def _directive_(self): # noqa self._regex_() self.name_last_node('value') - self._define(['name', 'value'], []) + self._define( + ['name', 'value'], + [], + ) with self._option(): with self._group(): self._token('whitespace') @@ -146,11 +157,15 @@ def _directive_(self): # noqa with self._option(): self._constant('None') self._error( - 'expecting one of: ' "'False' 'None' " + 'expecting one of: ' + "'False' 'None' " # noqa: COM812 ) self.name_last_node('value') - self._define(['name', 'value'], []) + self._define( + ['name', 'value'], + [], + ) with self._option(): with self._group(): with self._choice(): @@ -165,7 +180,7 @@ def _directive_(self): # noqa self._error( 'expecting one of: ' "'ignorecase' 'left_recursion'" - "'nameguard' 'parseinfo'" + "'nameguard' 'parseinfo'" # noqa: COM812 ) self.name_last_node('name') self._cut() @@ -177,13 +192,22 @@ def _directive_(self): # noqa self._boolean_() self.name_last_node('value') - self._define(['value'], []) + self._define( + ['value'], + [], + ) with self._option(): self._constant(True) self.name_last_node('value') - self._error('expecting one of: ' "'::'") + self._error( + 'expecting one of: ' + "'::'" # noqa: COM812 + ) - self._define(['name', 'value'], []) + self._define( + ['name', 'value'], + [], + ) with self._option(): with self._group(): self._token('grammar') @@ -194,7 +218,10 @@ def _directive_(self): # noqa self._word_() self.name_last_node('value') - self._define(['name', 'value'], []) + self._define( + ['name', 'value'], + [], + ) with self._option(): with self._group(): self._token('namechars') @@ -205,27 +232,33 @@ def _directive_(self): # noqa self._string_() self.name_last_node('value') - self._define(['name', 'value'], []) + self._define( + ['name', 'value'], + [], + ) self._error( 'expecting one of: ' "'comments' 'eol_comments' 'grammar'" "'ignorecase' 'left_recursion'" "'namechars' 'nameguard' 'parseinfo'" - "'whitespace'" + "'whitespace'" # noqa: COM812 ) self._cut() - self._define(['name', 'value'], []) + self._define( + ['name', 'value'], + [], + ) @tatsumasu() - def _keywords_(self): # noqa + def _keywords_(self): + def block0(): self._keywords_() - self._positive_closure(block0) @tatsumasu() - def _keyword_(self): # noqa + def _keyword_(self): self._token('@@keyword') self._cut() self._token('::') @@ -241,12 +274,14 @@ def block0(): self._token(':') with self._option(): self._token('=') - self._error('expecting one of: ' "':' '='") - + self._error( + 'expecting one of: ' + "':' '='" # noqa: COM812 + ) self._closure(block0) @tatsumasu() - def _paramdef_(self): # noqa + def _paramdef_(self): with self._choice(): with self._option(): self._token('::') @@ -254,7 +289,10 @@ def _paramdef_(self): # noqa self._params_() self.name_last_node('params') - self._define(['params'], []) + self._define( + ['params'], + [], + ) with self._option(): self._token('(') self._cut() @@ -271,21 +309,33 @@ def _paramdef_(self): # noqa self._kwparams_() self.name_last_node('kwparams') - self._define(['kwparams', 'params'], []) + self._define( + ['kwparams', 'params'], + [], + ) with self._option(): self._params_() self.name_last_node('params') - self._error('expecting one of: ' ' ') + self._error( + 'expecting one of: ' + ' ' # noqa: COM812 + ) self._token(')') - self._define(['kwparams', 'params'], []) - self._error('expecting one of: ' "'(' '::'") + self._define( + ['kwparams', 'params'], + [], + ) + self._error( + 'expecting one of: ' + "'(' '::'" # noqa: COM812 + ) @tatsumasu('Rule') - def _rule_(self): # noqa + def _rule_(self): + def block1(): self._decorator_() - self._closure(block1) self.name_last_node('decorators') self._name_() @@ -299,7 +349,10 @@ def block1(): self._params_() self.name_last_node('params') - self._define(['params'], []) + self._define( + ['params'], + [], + ) with self._option(): self._token('(') self._cut() @@ -316,24 +369,37 @@ def block1(): self._kwparams_() self.name_last_node('kwparams') - self._define(['kwparams', 'params'], []) + self._define( + ['kwparams', 'params'], + [], + ) with self._option(): self._params_() self.name_last_node('params') self._error( - 'expecting one of: ' ' ' + 'expecting one of: ' + ' ' # noqa: COM812 ) self._token(')') - self._define(['kwparams', 'params'], []) - self._error('expecting one of: ' "'(' '::'") + self._define( + ['kwparams', 'params'], + [], + ) + self._error( + 'expecting one of: ' + "'(' '::'" # noqa: COM812 + ) with self._optional(): self._token('<') self._cut() self._known_name_() self.name_last_node('base') - self._define(['base'], []) + self._define( + ['base'], + [], + ) self._token('=') self._cut() self._expre_() @@ -342,11 +408,12 @@ def block1(): self._cut() self._define( - ['base', 'decorators', 'exp', 'kwparams', 'name', 'params'], [] + ['base', 'decorators', 'exp', 'kwparams', 'name', 'params'], + [], ) @tatsumasu() - def _decorator_(self): # noqa + def _decorator_(self): self._token('@') with self._ifnot(): self._token('@') @@ -359,11 +426,14 @@ def _decorator_(self): # noqa self._token('name') with self._option(): self._token('nomemo') - self._error('expecting one of: ' "'name' 'nomemo' 'override'") + self._error( + 'expecting one of: ' + "'name' 'nomemo' 'override'" # noqa: COM812 + ) self.name_last_node('@') @tatsumasu() - def _params_(self): # noqa + def _params_(self): self._first_param_() self.add_last_node_to_name('@') @@ -374,11 +444,10 @@ def block1(): with self._ifnot(): self._token('=') self._cut() - self._closure(block1) @tatsumasu() - def _first_param_(self): # noqa + def _first_param_(self): with self._choice(): with self._option(): self._path_() @@ -388,21 +457,21 @@ def _first_param_(self): # noqa 'expecting one of: ' '(?!\\d)\\w+(?:::(?!\\d)\\w+)+ ' ' ' - ' ' + ' ' # noqa: COM812 ) @tatsumasu() - def _kwparams_(self): # noqa + def _kwparams_(self): + def sep0(): self._token(',') def block0(): self._pair_() - self._positive_gather(block0, sep0) @tatsumasu() - def _pair_(self): # noqa + def _pair_(self): self._word_() self.add_last_node_to_name('@') self._token('=') @@ -411,7 +480,7 @@ def _pair_(self): # noqa self.add_last_node_to_name('@') @tatsumasu() - def _expre_(self): # noqa + def _expre_(self): with self._choice(): with self._option(): self._choice_() @@ -420,11 +489,11 @@ def _expre_(self): # noqa self._error( 'expecting one of: ' "'|'