From fd9d07dfb6e88621babc7b1bdcc7cfa2fff2de5c Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner Date: Wed, 6 Nov 2024 15:48:16 -0600 Subject: [PATCH] Bump ruff Python compat target to 3.10 --- pymbolic/geometric_algebra/__init__.py | 6 ++--- pymbolic/geometric_algebra/primitives.py | 3 ++- pymbolic/interop/ast.py | 11 +--------- pymbolic/interop/matchpy/__init__.py | 6 ++--- pymbolic/interop/matchpy/mapper.py | 3 ++- pymbolic/interop/matchpy/tofrom.py | 3 ++- pymbolic/mapper/__init__.py | 28 +++++++++++------------- pymbolic/mapper/coefficient.py | 4 ++-- pymbolic/mapper/collector.py | 11 +++++----- pymbolic/mapper/constant_folder.py | 2 +- pymbolic/mapper/dependency.py | 7 +++--- pymbolic/mapper/differentiator.py | 2 +- pymbolic/mapper/optimize.py | 2 +- pymbolic/mapper/substitutor.py | 3 ++- pymbolic/mapper/unifier.py | 2 +- pymbolic/parser.py | 10 ++++----- pymbolic/primitives.py | 12 +++++----- pymbolic/traits.py | 2 +- pymbolic/typing.py | 24 ++++++++++---------- pyproject.toml | 4 ---- test/conftest.py | 8 ------- 21 files changed, 65 insertions(+), 88 deletions(-) delete mode 100644 test/conftest.py diff --git a/pymbolic/geometric_algebra/__init__.py b/pymbolic/geometric_algebra/__init__.py index de650a0..c14cfba 100644 --- a/pymbolic/geometric_algebra/__init__.py +++ b/pymbolic/geometric_algebra/__init__.py @@ -24,9 +24,9 @@ """ from abc import ABC, abstractmethod -from collections.abc import Mapping +from collections.abc import Mapping, Sequence from dataclasses import dataclass -from typing import Any, Dict, Generic, Sequence, TypeVar, cast +from typing import Any, Generic, TypeVar, cast import numpy as np @@ -590,7 +590,7 @@ def __init__( else: new_data[bits] = new_coeff else: - new_data = cast(Dict[int, CoeffT], data) + new_data = cast(dict[int, CoeffT], data) # }}} diff --git a/pymbolic/geometric_algebra/primitives.py b/pymbolic/geometric_algebra/primitives.py index b8140f3..00cf299 100644 --- a/pymbolic/geometric_algebra/primitives.py +++ b/pymbolic/geometric_algebra/primitives.py @@ -26,7 +26,8 @@ # This is experimental, undocumented, and could go away any second. # Consider yourself warned. -from typing import ClassVar, Hashable +from collections.abc import Hashable +from typing import ClassVar from pymbolic.primitives import Expression, Variable, expr_dataclass from pymbolic.typing import ExpressionT diff --git a/pymbolic/interop/ast.py b/pymbolic/interop/ast.py index 8db8522..d4090e9 100644 --- a/pymbolic/interop/ast.py +++ b/pymbolic/interop/ast.py @@ -457,19 +457,10 @@ def to_evaluatable_python_function(expr: ExpressionT, def foo(*, E, S): return S // 32 + E % 32 """ - import sys from pymbolic.mapper.dependency import CachedDependencyMapper - if sys.version_info < (3, 9): - try: - from astunparse import unparse - except ImportError: - raise RuntimeError("'to_evaluate_python_function' needs" - "astunparse for Py<3.9. Install via `pip" - " install astunparse`") from None - else: - unparse = ast.unparse + unparse = ast.unparse dep_mapper = CachedDependencyMapper(composite_leaves=True) deps = sorted({dep.name for dep in dep_mapper(expr)}) diff --git a/pymbolic/interop/matchpy/__init__.py b/pymbolic/interop/matchpy/__init__.py index 38e8156..a7a9e91 100644 --- a/pymbolic/interop/matchpy/__init__.py +++ b/pymbolic/interop/matchpy/__init__.py @@ -42,9 +42,10 @@ import abc +from collections.abc import Callable, Iterable, Iterator, Mapping from dataclasses import dataclass, field, fields from functools import partial -from typing import Callable, ClassVar, Generic, Iterable, Iterator, Mapping, TypeVar +from typing import ClassVar, Generic, TypeAlias, TypeVar from matchpy import ( Arity, @@ -54,7 +55,6 @@ ReplacementRule, Wildcard as BaseWildcard, ) -from typing_extensions import TypeAlias import pymbolic.primitives as p from pymbolic.typing import ScalarT @@ -85,7 +85,7 @@ def head(self): def __lt__(self, other): # Used by matchpy internally to order subexpressions - if not isinstance(other, (Expression,)): + if not isinstance(other, Expression): return NotImplemented if type(other) is type(self): if self.value == other.value: diff --git a/pymbolic/interop/matchpy/mapper.py b/pymbolic/interop/matchpy/mapper.py index 1af6aa0..44f25b6 100644 --- a/pymbolic/interop/matchpy/mapper.py +++ b/pymbolic/interop/matchpy/mapper.py @@ -1,6 +1,7 @@ from __future__ import annotations -from typing import Any, Callable +from collections.abc import Callable +from typing import Any from pymbolic.interop.matchpy import PymbolicOp diff --git a/pymbolic/interop/matchpy/tofrom.py b/pymbolic/interop/matchpy/tofrom.py index e4ae9d9..6399688 100644 --- a/pymbolic/interop/matchpy/tofrom.py +++ b/pymbolic/interop/matchpy/tofrom.py @@ -1,7 +1,8 @@ from __future__ import annotations +from collections.abc import Callable from dataclasses import dataclass -from typing import Any, Callable +from typing import Any import multiset import numpy as np diff --git a/pymbolic/mapper/__init__.py b/pymbolic/mapper/__init__.py index 34dc9ab..2a32cae 100644 --- a/pymbolic/mapper/__init__.py +++ b/pymbolic/mapper/__init__.py @@ -24,21 +24,19 @@ """ from abc import ABC, abstractmethod -from collections.abc import Mapping +from collections.abc import Callable, Hashable, Iterable, Mapping, Set from typing import ( TYPE_CHECKING, - AbstractSet, - Callable, + Concatenate, Generic, - Hashable, - Iterable, + TypeAlias, TypeVar, cast, ) from warnings import warn from immutabledict import immutabledict -from typing_extensions import Concatenate, ParamSpec, TypeAlias, TypeIs +from typing_extensions import ParamSpec, TypeIs import pymbolic.primitives as p from pymbolic.typing import ArithmeticExpressionT, ExpressionT @@ -640,7 +638,7 @@ class CachedCombineMapper(CachedMapper, CombineMapper): CollectedT = TypeVar("CollectedT") -class Collector(CombineMapper[AbstractSet[CollectedT], P]): +class Collector(CombineMapper[Set[CollectedT], P]): """A subclass of :class:`CombineMapper` for the common purpose of collecting data derived from an expression in a set that gets 'unioned' across children at each non-leaf node in the expression tree. @@ -651,34 +649,34 @@ class Collector(CombineMapper[AbstractSet[CollectedT], P]): """ def combine(self, - values: Iterable[AbstractSet[CollectedT]] - ) -> AbstractSet[CollectedT]: + values: Iterable[Set[CollectedT]] + ) -> Set[CollectedT]: import operator from functools import reduce return reduce(operator.or_, values, set()) def map_constant(self, expr: object, - *args: P.args, **kwargs: P.kwargs) -> AbstractSet[CollectedT]: + *args: P.args, **kwargs: P.kwargs) -> Set[CollectedT]: return set() def map_variable(self, expr: p.Variable, - *args: P.args, **kwargs: P.kwargs) -> AbstractSet[CollectedT]: + *args: P.args, **kwargs: P.kwargs) -> Set[CollectedT]: return set() def map_wildcard(self, expr: p.Wildcard, - *args: P.args, **kwargs: P.kwargs) -> AbstractSet[CollectedT]: + *args: P.args, **kwargs: P.kwargs) -> Set[CollectedT]: return set() def map_dot_wildcard(self, expr: p.DotWildcard, - *args: P.args, **kwargs: P.kwargs) -> AbstractSet[CollectedT]: + *args: P.args, **kwargs: P.kwargs) -> Set[CollectedT]: return set() def map_star_wildcard(self, expr: p.StarWildcard, - *args: P.args, **kwargs: P.kwargs) -> AbstractSet[CollectedT]: + *args: P.args, **kwargs: P.kwargs) -> Set[CollectedT]: return set() def map_function_symbol(self, expr: p.FunctionSymbol, - *args: P.args, **kwargs: P.kwargs) -> AbstractSet[CollectedT]: + *args: P.args, **kwargs: P.kwargs) -> Set[CollectedT]: return set() diff --git a/pymbolic/mapper/coefficient.py b/pymbolic/mapper/coefficient.py index 54e45d1..6a7feb5 100644 --- a/pymbolic/mapper/coefficient.py +++ b/pymbolic/mapper/coefficient.py @@ -23,8 +23,8 @@ THE SOFTWARE. """ -from collections.abc import Collection -from typing import Literal, Mapping, TypeAlias, cast +from collections.abc import Collection, Mapping +from typing import Literal, TypeAlias, cast import pymbolic.primitives as p from pymbolic.mapper import Mapper diff --git a/pymbolic/mapper/collector.py b/pymbolic/mapper/collector.py index e0c80db..5b21194 100644 --- a/pymbolic/mapper/collector.py +++ b/pymbolic/mapper/collector.py @@ -26,7 +26,8 @@ THE SOFTWARE. """ -from typing import AbstractSet, Sequence, cast +from collections.abc import Sequence, Set +from typing import cast import pymbolic import pymbolic.primitives as p @@ -43,7 +44,7 @@ class TermCollector(IdentityMapper[[]]): coefficients and are not used for term collection. """ - def __init__(self, parameters: AbstractSet[p.AlgebraicLeaf] | None = None): + def __init__(self, parameters: Set[p.AlgebraicLeaf] | None = None): if parameters is None: parameters = set() self.parameters = parameters @@ -53,7 +54,7 @@ def get_dependencies(self, expr: ExpressionT) -> DependenciesT: return DependencyMapper()(expr) def split_term(self, mul_term: ExpressionT) -> tuple[ - AbstractSet[tuple[ArithmeticExpressionT, ArithmeticExpressionT]], + Set[tuple[ArithmeticExpressionT, ArithmeticExpressionT]], ArithmeticExpressionT ]: """Returns a pair consisting of: @@ -81,7 +82,7 @@ def exponent(term: ExpressionT) -> ArithmeticExpressionT: if isinstance(mul_term, Product): terms: Sequence[ExpressionT] = mul_term.children - elif isinstance(mul_term, (Power, AlgebraicLeaf)): + elif isinstance(mul_term, Power | AlgebraicLeaf): terms = [mul_term] elif not bool(self.get_dependencies(mul_term)): terms = [mul_term] @@ -114,7 +115,7 @@ def exponent(term: ExpressionT) -> ArithmeticExpressionT: def map_sum(self, expr: p.Sum) -> ExpressionT: term2coeff: dict[ - AbstractSet[tuple[ArithmeticExpressionT, ArithmeticExpressionT]], + Set[tuple[ArithmeticExpressionT, ArithmeticExpressionT]], ArithmeticExpressionT] = {} for child in expr.children: term, coeff = self.split_term(child) diff --git a/pymbolic/mapper/constant_folder.py b/pymbolic/mapper/constant_folder.py index 9bf31b8..e68971a 100644 --- a/pymbolic/mapper/constant_folder.py +++ b/pymbolic/mapper/constant_folder.py @@ -70,7 +70,7 @@ def fold(self, assert is_arithmetic_expression(child) if isinstance(child, klass): - assert isinstance(child, (Sum, Product)) + assert isinstance(child, Sum | Product) queue = list(child.children) + queue else: if self.is_constant(child): diff --git a/pymbolic/mapper/dependency.py b/pymbolic/mapper/dependency.py index a4e5b0f..89b91db 100644 --- a/pymbolic/mapper/dependency.py +++ b/pymbolic/mapper/dependency.py @@ -28,15 +28,14 @@ THE SOFTWARE. """ -from typing import AbstractSet - -from typing_extensions import TypeAlias +from collections.abc import Set +from typing import TypeAlias import pymbolic.primitives as p from pymbolic.mapper import CachedMapper, Collector, CSECachingMapperMixin, P -DependenciesT: TypeAlias = AbstractSet[p.AlgebraicLeaf | p.CommonSubexpression] +DependenciesT: TypeAlias = Set[p.AlgebraicLeaf | p.CommonSubexpression] class DependencyMapper( diff --git a/pymbolic/mapper/differentiator.py b/pymbolic/mapper/differentiator.py index 87b9c36..c5ec059 100644 --- a/pymbolic/mapper/differentiator.py +++ b/pymbolic/mapper/differentiator.py @@ -222,7 +222,7 @@ def differentiate(expression, variable, func_mapper=map_math_functions_by_name, allowed_nonsmoothness="none"): - if not isinstance(variable, (primitives.Variable, primitives.Subscript)): + if not isinstance(variable, primitives.Variable | primitives.Subscript): variable = primitives.make_variable(variable) from pymbolic import flatten return flatten(DifferentiationMapper( diff --git a/pymbolic/mapper/optimize.py b/pymbolic/mapper/optimize.py index aedf784..a07757c 100644 --- a/pymbolic/mapper/optimize.py +++ b/pymbolic/mapper/optimize.py @@ -302,7 +302,7 @@ def wrapper(cls: type) -> type: if not name.startswith("__") or name == "__call__": method = getattr(cls, name) if (not callable(method) - or isinstance(method, (property, cached_property))): + or isinstance(method, property | cached_property)): # properties don't have *args, **kwargs continue diff --git a/pymbolic/mapper/substitutor.py b/pymbolic/mapper/substitutor.py index 0418634..2194c1c 100644 --- a/pymbolic/mapper/substitutor.py +++ b/pymbolic/mapper/substitutor.py @@ -38,7 +38,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ -from typing import Any, Callable +from collections.abc import Callable +from typing import Any from useful_types import SupportsGetItem, SupportsItems diff --git a/pymbolic/mapper/unifier.py b/pymbolic/mapper/unifier.py index c4eec56..9409efd 100644 --- a/pymbolic/mapper/unifier.py +++ b/pymbolic/mapper/unifier.py @@ -120,7 +120,7 @@ def treat_mismatch(self, expr, other, urecs): raise NotImplementedError def unification_record_from_equation(self, lhs, rhs): - if isinstance(lhs, (tuple, list)) or isinstance(rhs, (tuple, list)): + if isinstance(lhs, tuple | list) or isinstance(rhs, tuple | list): # Always force lists/tuples to agree elementwise, never # generate a unification record between them directly. # This pushes the matching process down to the elementwise diff --git a/pymbolic/parser.py b/pymbolic/parser.py index 6171d66..fd4248f 100644 --- a/pymbolic/parser.py +++ b/pymbolic/parser.py @@ -25,11 +25,11 @@ THE SOFTWARE. """ +from collections.abc import Sequence from sys import intern -from typing import ClassVar, Sequence, Tuple, Union +from typing import ClassVar, TypeAlias from immutabledict import immutabledict -from typing_extensions import TypeAlias import pytools.lex from pytools import memoize_method @@ -128,7 +128,7 @@ def __hash__(self) -> int: # type: ignore[override] LexTable: TypeAlias = Sequence[ - Tuple[str, Union[pytools.lex.RE, Tuple[Union[str, pytools.lex.RE], ...]]]] + tuple[str, pytools.lex.RE | tuple[str | pytools.lex.RE, ...]]] class Parser: @@ -500,7 +500,7 @@ def parse_postfix(self, pstate, min_precedence, left_exp): pstate.advance() if pstate.is_at_end() or pstate.next_tag() is _closepar: - if isinstance(left_exp, (tuple, list)) \ + if isinstance(left_exp, tuple | list) \ and not isinstance(left_exp, FinalizedContainer): # left_expr is a container with trailing commas pass @@ -508,7 +508,7 @@ def parse_postfix(self, pstate, min_precedence, left_exp): left_exp = (left_exp,) else: new_el = self.parse_expression(pstate, _PREC_COMMA) - if isinstance(left_exp, (tuple, list)) \ + if isinstance(left_exp, tuple | list) \ and not isinstance(left_exp, FinalizedContainer): left_exp = (*left_exp, new_el) else: diff --git a/pymbolic/primitives.py b/pymbolic/primitives.py index 181f166..9718f6b 100644 --- a/pymbolic/primitives.py +++ b/pymbolic/primitives.py @@ -24,25 +24,23 @@ """ import re +from collections.abc import Callable, Iterable, Mapping from dataclasses import dataclass, fields from sys import intern from typing import ( TYPE_CHECKING, Any, - Callable, ClassVar, - Iterable, - Mapping, NoReturn, Protocol, - Type, + TypeAlias, TypeVar, cast, ) from warnings import warn from immutabledict import immutabledict -from typing_extensions import TypeAlias, TypeIs, dataclass_transform +from typing_extensions import TypeIs, dataclass_transform from . import traits from .typing import ArithmeticExpressionT, ExpressionT, NumberT, ScalarT @@ -1042,7 +1040,7 @@ def {cls.__name__}_setstate(self, state): # {{{ assign mapper_method - mm_cls = cast(Type[_HasMapperMethod], cls) + mm_cls = cast(type[_HasMapperMethod], cls) snake_clsname = _CAMEL_TO_SNAKE_RE.sub("_", mm_cls.__name__).lower() default_mapper_method_name = f"map_{snake_clsname}" @@ -1916,7 +1914,7 @@ def is_zero(value: object) -> bool: def wrap_in_cse(expr: ExpressionT, prefix=None) -> ExpressionT: - if isinstance(expr, (Variable, Subscript)): + if isinstance(expr, Variable | Subscript): return expr if isinstance(expr, CommonSubexpression): diff --git a/pymbolic/traits.py b/pymbolic/traits.py index 321d29b..4411cc2 100644 --- a/pymbolic/traits.py +++ b/pymbolic/traits.py @@ -40,7 +40,7 @@ def traits(x): try: return x.traits() except AttributeError: - if isinstance(x, (complex, float)): + if isinstance(x, complex | float): return FieldTraits() elif isinstance(x, int): return IntegerTraits() diff --git a/pymbolic/typing.py b/pymbolic/typing.py index c1ecaa0..a16ed6c 100644 --- a/pymbolic/typing.py +++ b/pymbolic/typing.py @@ -25,9 +25,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Tuple, TypeVar, Union - -from typing_extensions import TypeAlias +from typing import TYPE_CHECKING, TypeAlias, TypeVar, Union # FIXME: This is a lie. Many more constant types (e.g. numpy and such) @@ -55,15 +53,15 @@ # (e.g. 'Unsupported operand types for * ("Decimal" and "Fraction")') # And leaving them out doesn't really make any of this more precise. -_StdlibInexactNumberT = Union[float, complex] +_StdlibInexactNumberT = float | complex if TYPE_CHECKING: # Yes, type-checking pymbolic will require numpy. That's OK. import numpy as np - BoolT = Union[bool, np.bool_] - IntegerT: TypeAlias = Union[int, np.integer] - InexactNumberT: TypeAlias = Union[_StdlibInexactNumberT, np.inexact] + BoolT = bool | np.bool_ + IntegerT: TypeAlias = int | np.integer + InexactNumberT: TypeAlias = _StdlibInexactNumberT | np.inexact else: try: import numpy as np @@ -72,18 +70,18 @@ IntegerT: TypeAlias = int InexactNumberT: TypeAlias = _StdlibInexactNumberT else: - BoolT = Union[bool, np.bool_] - IntegerT: TypeAlias = Union[int, np.integer] - InexactNumberT: TypeAlias = Union[_StdlibInexactNumberT, np.inexact] + BoolT = bool | np.bool_ + IntegerT: TypeAlias = int | np.integer + InexactNumberT: TypeAlias = _StdlibInexactNumberT | np.inexact -NumberT: TypeAlias = Union[IntegerT, InexactNumberT] -ScalarT: TypeAlias = Union[NumberT, BoolT] +NumberT: TypeAlias = IntegerT | InexactNumberT +ScalarT: TypeAlias = NumberT | BoolT _ScalarOrExpression = Union[ScalarT, "Expression"] ArithmeticExpressionT: TypeAlias = Union[NumberT, "Expression"] -ExpressionT: TypeAlias = Union[_ScalarOrExpression, Tuple["ExpressionT", ...]] +ExpressionT: TypeAlias = _ScalarOrExpression | tuple["ExpressionT", ...] ArithmeticOrExpressionT = TypeVar( "ArithmeticOrExpressionT", diff --git a/pyproject.toml b/pyproject.toml index b106737..e4f2c6e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -65,10 +65,6 @@ include = [ [tool.ruff] preview = true -# FIXME set this to 3.10 before merging -# https://github.com/inducer/pymbolic/pull/152 -target-version = "py38" - [tool.ruff.lint] extend-select = [ "B", # flake8-bugbear diff --git a/test/conftest.py b/test/conftest.py deleted file mode 100644 index 729a220..0000000 --- a/test/conftest.py +++ /dev/null @@ -1,8 +0,0 @@ -from __future__ import annotations - -import sys - - -collect_ignore = [] -if sys.version_info < (3, 10): - collect_ignore.append("test_pattern_match.py")