From 371d28d8a45c55f54fd6b113e1ef688773002aad Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner <inform@tiker.net> Date: Wed, 17 Jul 2024 13:37:15 -0500 Subject: [PATCH] Switch to ruff, fix issues --- .github/workflows/ci.yml | 13 +++------ .gitlab-ci.yml | 8 +++--- benchmarks/bench_translations.py | 4 +-- examples/expansion-toys.py | 3 ++- pyproject.toml | 45 ++++++++++++++++++++++++++++++++ setup.py | 2 +- sumpy/assignment_collection.py | 4 +-- sumpy/codegen.py | 2 +- sumpy/cse.py | 2 +- sumpy/expansion/__init__.py | 6 ++--- sumpy/kernel.py | 4 +-- sumpy/p2p.py | 2 +- sumpy/qbx.py | 5 ++-- sumpy/tools.py | 8 +++--- test/test_misc.py | 2 +- 15 files changed, 76 insertions(+), 34 deletions(-) create mode 100644 pyproject.toml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6a2c714a..0a1dcf6f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,20 +8,15 @@ on: - cron: '17 3 * * 0' jobs: - flake8: - name: Flake8 + ruff: + name: Ruff runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - - uses: actions/setup-python@v5 - with: - # matches compat target in setup.py - python-version: '3.8' - name: "Main Script" run: | - curl -L -O https://gitlab.tiker.net/inducer/ci-support/raw/main/prepare-and-run-flake8.sh - . ./prepare-and-run-flake8.sh "$(basename $GITHUB_REPOSITORY)" test examples benchmarks + pipx install ruff + ruff check pylint: name: Pylint diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 85b7eb07..2326e653 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -118,13 +118,13 @@ Documentation: tags: - linux -Flake8: +Ruff: stage: test script: - - curl -L -O https://gitlab.tiker.net/inducer/ci-support/raw/main/prepare-and-run-flake8.sh - - . ./prepare-and-run-flake8.sh "$CI_PROJECT_NAME" test examples benchmarks + - pix install ruff + - ruff check tags: - - python3 + - docker-runner except: - tags diff --git a/benchmarks/bench_translations.py b/benchmarks/bench_translations.py index f8d718f4..8c31eb8b 100644 --- a/benchmarks/bench_translations.py +++ b/benchmarks/bench_translations.py @@ -45,7 +45,7 @@ class TranslationBenchmarkSuite: def setup(self, param): logging.basicConfig(level=logging.INFO) - np.random.seed(17) + np.random.seed(17) # noqa: NPY002 if self.__class__ == TranslationBenchmarkSuite: raise NotImplementedError mpole_expn_class = self.mpole_expn_class @@ -78,7 +78,7 @@ class TranslationBenchmarkSuite: insns = to_loopy_insns(sac.assignments.items()) counter = pymbolic.mapper.flop_counter.CSEAwareFlopCounter() - return sum([counter.rec(insn.expression)+1 for insn in insns]) + return sum(counter.rec(insn.expression)+1 for insn in insns) track_m2l_op_count.unit = "ops" track_m2l_op_count.timeout = 300.0 diff --git a/examples/expansion-toys.py b/examples/expansion-toys.py index 48647d0e..6e7d66b3 100644 --- a/examples/expansion-toys.py +++ b/examples/expansion-toys.py @@ -29,9 +29,10 @@ def main(): # HelmholtzKernel(2), extra_kernel_kwargs={"k": 0.3}, ) + rng = np.random.default_rng() pt_src = t.PointSources( tctx, - np.random.rand(2, 50) - 0.5, + rng.uniform(size=(2, 50)) - 0.5, np.ones(50)) fp = FieldPlotter([3, 0], extent=8) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..11cf370c --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,45 @@ +[tool.ruff] +target-version = "py38" +preview = true + +[tool.ruff.lint] +extend-select = [ + "B", # flake8-bugbear + "C", # flake8-comprehensions + "E", # pycodestyle + "F", # pyflakes + "G", # flake8-logging-format + # "I", # flake8-isort + "N", # pep8-naming + "NPY", # numpy + "Q", # flake8-quotes + # "UP", # pyupgrade + # "RUF", # ruff + # "W", # pycodestyle +] +extend-ignore = [ + "C90", # McCabe complexity + "E221", # multiple spaces before operator + "E226", # missing whitespace around arithmetic operator + "E402", # module-level import not at top of file + "UP006", # updated annotations due to __future__ import + "UP007", # updated annotations due to __future__ import + "UP031", # use f-strings instead of % + "UP032", # use f-strings instead of .format + + # TODO + "E265", # comment format + "F841", # unused local +] + +[tool.ruff.lint.flake8-quotes] +docstring-quotes = "double" +inline-quotes = "double" +multiline-quotes = "double" + +[tool.ruff.lint.isort] +combine-as-imports = true +known-local-folder = [ + "pytools", +] +lines-after-imports = 2 diff --git a/setup.py b/setup.py index 359a3ea5..c6fb7427 100644 --- a/setup.py +++ b/setup.py @@ -50,7 +50,7 @@ def find_git_revision(tree_root): if retcode != 0: from warnings import warn - warn("unable to find git revision") + warn("unable to find git revision", stacklevel=1) return None return git_rev diff --git a/sumpy/assignment_collection.py b/sumpy/assignment_collection.py index 81bb066f..5115714d 100644 --- a/sumpy/assignment_collection.py +++ b/sumpy/assignment_collection.py @@ -216,8 +216,8 @@ class SymbolicAssignmentCollection: del self.assignments[name] self.assignments[name] = new_expr - logger.info("common subexpression elimination: done after {dur:.2f} s" - .format(dur=time.time() - start_time)) + logger.info("common subexpression elimination: done after %.2f s", + time.time() - start_time) return new_extra_exprs # }}} diff --git a/sumpy/codegen.py b/sumpy/codegen.py index 670d0729..5c51cd9c 100644 --- a/sumpy/codegen.py +++ b/sumpy/codegen.py @@ -481,7 +481,7 @@ class BigIntegerKiller(CSECachingIdentityMapper, CallExternalRecMapper): if int(expr_as_float) != int(expr): from warnings import warn warn(f"Converting '{expr}' to " - f"'{self.float_type.__name__}' loses digits") + f"'{self.float_type.__name__}' loses digits", stacklevel=1) # Suppress further warnings. self.warn = False diff --git a/sumpy/cse.py b/sumpy/cse.py index f7023aa1..635c26f1 100644 --- a/sumpy/cse.py +++ b/sumpy/cse.py @@ -527,7 +527,7 @@ def tree_cse(exprs, symbols, opt_subs=None): try: sym = next(symbols) except StopIteration: - raise ValueError("Symbols iterator ran out of symbols.") + raise ValueError("Symbols iterator ran out of symbols.") from None subs[orig_expr] = sym replacements.append((sym, new_expr)) diff --git a/sumpy/expansion/__init__.py b/sumpy/expansion/__init__.py index dc3ce3ba..493ff710 100644 --- a/sumpy/expansion/__init__.py +++ b/sumpy/expansion/__init__.py @@ -734,9 +734,9 @@ class LinearPDEBasedExpansionTermsWrangler(ExpansionTermsWrangler): plog.done() - logger.debug("number of Taylor coefficients was reduced from {orig} to {red}" - .format(orig=len(self.get_full_coefficient_identifiers()), - red=len(stored_identifiers))) + logger.debug("number of Taylor coefficients was reduced from %d to %d", + len(self.get_full_coefficient_identifiers()), + len(stored_identifiers)) shape = (len(mis), len(stored_identifiers)) op = CSEMatVecOperator(from_input_coeffs_by_row, diff --git a/sumpy/kernel.py b/sumpy/kernel.py index 76027809..d3edefa0 100644 --- a/sumpy/kernel.py +++ b/sumpy/kernel.py @@ -1313,9 +1313,9 @@ class KernelMapper: def rec(self, kernel): try: method = getattr(self, kernel.mapper_method) - except AttributeError: + except AttributeError as err: raise RuntimeError("{} cannot handle {}".format( - type(self), type(kernel))) + type(self), type(kernel))) from err else: return method(kernel) diff --git a/sumpy/p2p.py b/sumpy/p2p.py index c5acdd9d..6babc237 100644 --- a/sumpy/p2p.py +++ b/sumpy/p2p.py @@ -704,7 +704,7 @@ class P2PFromCSR(P2PBase): for i, (array_name, array_size, array_dtype) in \ enumerate(zip(local_arrays, local_array_sizes, local_array_dtypes)): - if array_dtype not in [np.float, np.double]: + if issubclass(array_dtype.type, np.complexfloating): # pyopencl does not support complex data type vectors continue if array_size in [2, 3, 4, 8, 16]: diff --git a/sumpy/qbx.py b/sumpy/qbx.py index 9c903ab1..19ff0f7f 100644 --- a/sumpy/qbx.py +++ b/sumpy/qbx.py @@ -210,7 +210,8 @@ class LayerPotentialBase(KernelCacheMixin, KernelComputation): ["isrc_outer", f"{itgt_name}_inner"]) else: from warnings import warn - warn(f"don't know how to tune layer potential computation for '{dev}'") + warn(f"don't know how to tune layer potential computation for '{dev}'", + stacklevel=1) loopy_knl = lp.split_iname(loopy_knl, itgt_name, 128, outer_tag="g.0") loopy_knl = self._allow_redundant_execution_of_knl_scaling(loopy_knl) @@ -574,7 +575,7 @@ def find_jump_term(kernel, arg_provider): elif tgt_count == 1: from warnings import warn warn("jump terms for mixed derivatives (1 src+1 tgt) only available " - "for the double-layer potential") + "for the double-layer potential", stacklevel=1) i, = tgt_derivatives assert isinstance(i, int) return ( diff --git a/sumpy/tools.py b/sumpy/tools.py index 13acbbab..8c666b61 100644 --- a/sumpy/tools.py +++ b/sumpy/tools.py @@ -473,8 +473,8 @@ class KernelCacheMixin: logger.info("%s: kernel cache miss", self.name) if CACHING_ENABLED and not ( NO_CACHE_KERNELS and self.name in NO_CACHE_KERNELS): - logger.info("{}: kernel cache miss [key={}]".format( - self.name, cache_key)) + logger.info("%s: kernel cache miss [key=%d]", + self.name, cache_key) from pytools import MinRecursionLimit with MinRecursionLimit(3000): @@ -666,8 +666,8 @@ def to_complex_dtype(dtype): np_type = np.dtype(dtype).type try: return to_complex_type_dict[np_type] - except KeyError: - raise RuntimeError(f"Unknown dtype: {dtype}") + except KeyError as err: + raise RuntimeError(f"Unknown dtype: {dtype}") from err @dataclass(frozen=True) diff --git a/test/test_misc.py b/test/test_misc.py index 9cee476c..02842570 100644 --- a/test/test_misc.py +++ b/test/test_misc.py @@ -426,7 +426,7 @@ def test_as_scalar_pde_maxwell(): mu, epsilon = symbols("mu, epsilon") t = (0, 0, 0, 1) - pde = concat(curl(E) + diff(B, t), curl(B) - mu*epsilon*diff(E, t), + pde = concat(curl(E) + diff(B, t), curl(B) - mu*epsilon*diff(E, t), divergence(E), divergence(B)) as_scalar_pde(pde, 3) -- GitLab