diff --git a/pymbolic/algorithm.py b/pymbolic/algorithm.py index 9a6b9ae5827b6f60bd71c2af00c191ed7ee0539c..8f92085bfcb64a9eb81e934a9b19ceda06e69ac3 100644 --- a/pymbolic/algorithm.py +++ b/pymbolic/algorithm.py @@ -266,7 +266,7 @@ def sym_fft(x, sign=1): def csr_matrix_multiply(S, x): # noqa """Multiplies a :class:`scipy.sparse.csr_matrix` S by an object-array vector x. """ - h, w = S.shape + h, _w = S.shape import numpy result = numpy.empty_like(x) diff --git a/pymbolic/geometric_algebra/__init__.py b/pymbolic/geometric_algebra/__init__.py index 26d0cc0743f06e23136b662d7d71578d9d8d1fae..bf058333ec177fbeefe125261d1470456931b00e 100644 --- a/pymbolic/geometric_algebra/__init__.py +++ b/pymbolic/geometric_algebra/__init__.py @@ -1059,7 +1059,7 @@ class MultiVector: for bits, coeff in self.data.items(): result[log_table[bits]] = coeff except KeyError: - raise ValueError("multivector is not a purely grade-1") + raise ValueError("multivector is not a purely grade-1") from None if dtype is not None: return result diff --git a/pymbolic/geometric_algebra/mapper.py b/pymbolic/geometric_algebra/mapper.py index 618fb192e62080b8961fdd468a125b156c002037..b143c5cb1c58324e8dea680b36f236bb3e351471 100644 --- a/pymbolic/geometric_algebra/mapper.py +++ b/pymbolic/geometric_algebra/mapper.py @@ -121,7 +121,7 @@ class StringifyMapper(StringifyMapperBase): class GraphvizMapper(GraphvizMapperBase): def map_derivative_source(self, expr): self.lines.append( - '{} [label="D[{}]\",shape=ellipse];'.format( + '{} [label="D[{}]",shape=ellipse];'.format( self.get_id(expr), expr.nabla_id)) if not self.visit(expr, node_printed=True): return diff --git a/pymbolic/imperative/utils.py b/pymbolic/imperative/utils.py index ecd1e0ecab6e25e68eec3d51a5da594be68af127..6df33a697160db78a8b2b03401183b4ad426ba0a 100644 --- a/pymbolic/imperative/utils.py +++ b/pymbolic/imperative/utils.py @@ -142,7 +142,8 @@ def show_dot(dot_code, output_to=None): from warnings import warn warn("pymbolic.imperative.utils.show_dot is deprecated. " "It will stop working in July 2023. " - "Please use pytools.graphviz.show_dot instead.", DeprecationWarning) + "Please use pytools.graphviz.show_dot instead.", + DeprecationWarning, stacklevel=2) from pytools.graphviz import show_dot return show_dot(dot_code, output_to) diff --git a/pymbolic/interop/ast.py b/pymbolic/interop/ast.py index 0756a22a6ebfffa91b81eff8d14b1d997147a2c3..df2a49dcb43a040dc148e312d69edbc9bf85cbfc 100644 --- a/pymbolic/interop/ast.py +++ b/pymbolic/interop/ast.py @@ -133,9 +133,8 @@ class ASTToPymbolic(ASTMapper): op_constructor = self.bin_op_map[type(expr.op)] except KeyError: raise NotImplementedError( - "{} does not know how to map operator '{}'".format( - type(self).__name__, - type(expr.op).__name__)) + f"{type(self).__name__} does not know how to map operator " + f"'{type(expr.op).__name__}'") from None return op_constructor(self.rec(expr.left), self.rec(expr.right)) @@ -151,9 +150,8 @@ class ASTToPymbolic(ASTMapper): op_constructor = self.unary_op_map[type(expr.op)] except KeyError: raise NotImplementedError( - "{} does not know how to map operator '{}'".format( - type(self).__name__, - type(expr.op).__name__)) + f"{type(self).__name__} does not know how to map operator " + f"'{type(expr.op).__name__}'") from None return op_constructor(self.rec(expr.operand)) @@ -182,9 +180,8 @@ class ASTToPymbolic(ASTMapper): comp = self.comparison_op_map[type(op)] except KeyError: raise NotImplementedError( - "{} does not know how to map operator '{}'".format( - type(self).__name__, - type(op).__name__)) + f"{type(self).__name__} does not know how to map operator " + f"'{type(expr.op).__name__}'") from None # FIXME: Support strung-together comparisons right, = expr.comparators @@ -477,7 +474,7 @@ def to_evaluatable_python_function(expr: ExpressionT, except ImportError: raise RuntimeError("'to_evaluate_python_function' needs" "astunparse for Py<3.9. Install via `pip" - " install astunparse`") + " install astunparse`") from None else: unparse = ast.unparse diff --git a/pymbolic/mapper/evaluator.py b/pymbolic/mapper/evaluator.py index 6d596622de67a7109457663829ff78dc7e63fd54..cf9bce044132700a9b60f02f81d6bec7add86ec2 100644 --- a/pymbolic/mapper/evaluator.py +++ b/pymbolic/mapper/evaluator.py @@ -76,7 +76,7 @@ class EvaluationMapper(RecursiveMapper, CSECachingMapperMixin): try: return self.context[expr.name] except KeyError: - raise UnknownVariableError(expr.name) + raise UnknownVariableError(expr.name) from None def map_call(self, expr): return self.rec(expr.function)(*[self.rec(par) for par in expr.parameters]) diff --git a/pymbolic/mapper/optimize.py b/pymbolic/mapper/optimize.py index 16b796a8c2f1cf94848c4255b09f9ed3d5d7c1bf..54bd9fc2c851f820a9940039a519e26e44346f70 100644 --- a/pymbolic/mapper/optimize.py +++ b/pymbolic/mapper/optimize.py @@ -243,7 +243,7 @@ def optimize_mapper( def wrapper(cls): try: # Introduced in Py3.9 - ast.unparse + ast.unparse # noqa: B018 except AttributeError: return cls diff --git a/pymbolic/mapper/stringifier.py b/pymbolic/mapper/stringifier.py index 9e633c62f6a6d16f3e5b46ad27878d474fbebc57..e49fcc4f9103956afccdf05c56975847d3e8ee4a 100644 --- a/pymbolic/mapper/stringifier.py +++ b/pymbolic/mapper/stringifier.py @@ -479,12 +479,12 @@ class CSESplittingStringifyMapperMixin: def map_common_subexpression(self, expr, enclosing_prec, *args, **kwargs): # This is here for compatibility, in case the constructor did not get called. try: - self.cse_to_name + self.cse_to_name # noqa: B018 except AttributeError: from warnings import warn warn("Constructor of CSESplittingStringifyMapperMixin did not get " - "called. This is deprecated and will stop working in 2022.", - DeprecationWarning) + "called. This is deprecated and will stop working in 2022.", + DeprecationWarning, stacklevel=2) self.cse_to_name = {} self.cse_names = set() diff --git a/pymbolic/maxima.py b/pymbolic/maxima.py index 6c52dea4bf3d9e110ae905d6943fed50b505fab2..3eee265e22a3240de8e8626454df60a615c5e0d7 100644 --- a/pymbolic/maxima.py +++ b/pymbolic/maxima.py @@ -1,5 +1,6 @@ from pymbolic.interop.maxima import * # noqa from warnings import warn + warn("pymbolic.maxima is deprecated. Use pymbolic.interop.maxima instead", - DeprecationWarning) + DeprecationWarning, stacklevel=1) diff --git a/pymbolic/primitives.py b/pymbolic/primitives.py index 7f80b174a8a77871c73c35562aa259b3fadc45b8..621073fb2e7c89af92c1333c950e87ee732514ef 100644 --- a/pymbolic/primitives.py +++ b/pymbolic/primitives.py @@ -1349,7 +1349,7 @@ class Vector(Expression): "(a) numpy object arrays and " "(b) pymbolic.geometric_algebra.MultiVector " "(depending on the required semantics)", - DeprecationWarning) + DeprecationWarning, stacklevel=2) def __bool__(self): for i in self.children: diff --git a/pymbolic/sympy_interface.py b/pymbolic/sympy_interface.py index ed6eb21af826866fd0eb0c86f468b6ec4ffd4397..0b423751a3a00070adf1c07f831a304c8d745650 100644 --- a/pymbolic/sympy_interface.py +++ b/pymbolic/sympy_interface.py @@ -1,5 +1,6 @@ from pymbolic.interop.sympy import * # noqa from warnings import warn + warn("pymbolic.sympy_interface is deprecated. Use pymbolic.interop.sympy instead", - DeprecationWarning) + DeprecationWarning, stacklevel=1) diff --git a/pymbolic/traits.py b/pymbolic/traits.py index 6a6815faf10c8cf35f519a2e158ec03cd64cd8c9..58a5908b09e326ef9c131d59964f2c27f77add22 100644 --- a/pymbolic/traits.py +++ b/pymbolic/traits.py @@ -41,7 +41,7 @@ def traits(x): elif isinstance(x, int): return IntegerTraits() else: - raise NoTraitsError + raise NoTraitsError from None def common_traits(*args): diff --git a/pyproject.toml b/pyproject.toml index 57c58c0f81aec4a37c2f60846d4ad62769a73679..b416c1947a2d194fd7fdf0a7275b862cb3f53004 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,13 +42,9 @@ numpy = [ "numpy>=1.6", ] test = [ - "flake8", - "flake8-bugbear", - "flake8-comprehensions", - "flake8-pyproject", "mypy", - "pep8-naming", "pytest", + "ruff" ] [project.urls] @@ -60,15 +56,13 @@ include = [ "pymbolic*", ] -[tool.flake8] -max-line-length = 85 -inline-quotes = "double" -docstring-quotes = "double" -multiline-quotes = "double" -select = [ +[tool.ruff] +preview = true + +[tool.ruff.lint] +extend-select = [ "B", # flake8-bugbear "C", # flake8-comprehensions - "D", # pydocstyle "E", # pycodestyle "F", # pyflakes # "I", # flake8-isort @@ -77,19 +71,20 @@ select = [ "W", # pycodestyle ] extend-ignore = [ - "E123", # closing bracket does not match indentation - "E126", # continuation line over-indented - "E127", # continuation line over-indented - "E128", # continuation line under-indented + "C90", # McCabe complexity "E226", # missing whitespace around arithmetic operator "E241", # multiple spaces after comma "E242", # tab after comma "E402", # module level import not at the top of file - "W503", # line break before a binary operator ] exclude = [ "pymbolic/polynomial.py", ] -per-file-ignores = [ - "experiments/traversal-benchmark.py:E501", -] + +[tool.ruff.lint.per-file-ignores] +"experiments/traversal-benchmark.py" = ["E501"] + +[tool.ruff.lint.flake8-quotes] +inline-quotes = "double" +docstring-quotes = "double" +multiline-quotes = "double" diff --git a/test/test_pymbolic.py b/test/test_pymbolic.py index dc8152f8c998c7524bd004725778add683288fe1..12be1e6700e5297325f498c808a4cb2d03ce0a29 100644 --- a/test/test_pymbolic.py +++ b/test/test_pymbolic.py @@ -664,10 +664,10 @@ def test_latex_mapper(): "-output-directory=%s" % latex_dir, tex_file_path], universal_newlines=True) - except OSError: # FIXME: Should be FileNotFoundError on Py3 + except FileNotFoundError: pytest.skip("latex command not found") except subprocess.CalledProcessError as err: - raise AssertionError(str(err.output)) + raise AssertionError(str(err.output)) from None finally: shutil.rmtree(latex_dir)