diff options
author | Hernan Grecco <hgrecco@gmail.com> | 2023-05-09 19:45:34 -0300 |
---|---|---|
committer | Hernan Grecco <hgrecco@gmail.com> | 2023-05-09 19:45:34 -0300 |
commit | e5c8b03a02e650134d6139ad38305797a2c962c8 (patch) | |
tree | dd74d796f80994efe3741cc20763cc708f97a447 | |
parent | 10ac784342b2503a4f1b153ba2cbc4be72f75122 (diff) | |
download | pint-e5c8b03a02e650134d6139ad38305797a2c962c8.tar.gz |
Typing related fixes
-rw-r--r-- | pint/_typing.py | 63 | ||||
-rw-r--r-- | pint/compat.py | 24 | ||||
-rw-r--r-- | pint/delegates/txt_defparser/context.py | 8 | ||||
-rw-r--r-- | pint/delegates/txt_defparser/defaults.py | 2 | ||||
-rw-r--r-- | pint/delegates/txt_defparser/defparser.py | 2 | ||||
-rw-r--r-- | pint/delegates/txt_defparser/group.py | 4 | ||||
-rw-r--r-- | pint/delegates/txt_defparser/system.py | 4 | ||||
-rw-r--r-- | pint/errors.py | 2 | ||||
-rw-r--r-- | pint/facets/context/definitions.py | 6 | ||||
-rw-r--r-- | pint/facets/context/objects.py | 10 | ||||
-rw-r--r-- | pint/facets/group/definitions.py | 6 | ||||
-rw-r--r-- | pint/facets/plain/definitions.py | 2 | ||||
-rw-r--r-- | pint/facets/plain/quantity.py | 2 | ||||
-rw-r--r-- | pint/facets/plain/registry.py | 5 | ||||
-rw-r--r-- | pint/facets/system/definitions.py | 6 | ||||
-rw-r--r-- | pint/formatting.py | 38 |
16 files changed, 77 insertions, 107 deletions
diff --git a/pint/_typing.py b/pint/_typing.py index 5177e78..25263da 100644 --- a/pint/_typing.py +++ b/pint/_typing.py @@ -4,6 +4,7 @@ from typing import TYPE_CHECKING, Any, Callable, TypeVar, Union, Protocol from decimal import Decimal from fractions import Fraction +from .compat import TypeAlias, Never if TYPE_CHECKING: from .facets.plain import PlainQuantity as Quantity @@ -11,55 +12,6 @@ if TYPE_CHECKING: from .util import UnitsContainer -class ScalarProtocol(Protocol): - def __add__(self, other: Any) -> Any: - ... - - def __sub__(self, other: Any) -> Any: - ... - - def __mul__(self, other: Any) -> Any: - ... - - def __truediv__(self, other: Any) -> Any: - ... - - def __floordiv__(self, other: Any) -> Any: - ... - - def __mod__(self, other: Any) -> Any: - ... - - def __divmod__(self, other: Any) -> Any: - ... - - def __pow__(self, other: Any, modulo: Any) -> Any: - ... - - def __gt__(self, other: Any) -> bool: - ... - - def __lt__(self, other: Any) -> bool: - ... - - def __ge__(self, other: Any) -> bool: - ... - - def __le__(self, other: Any) -> bool: - ... - - -class ArrayProtocol(Protocol): - def __len__(self) -> int: - ... - - def __getitem__(self, key: Any) -> Any: - ... - - def __setitem__(self, key: Any, value: Any) -> None: - ... - - HAS_NUMPY = False if TYPE_CHECKING: from .compat import HAS_NUMPY @@ -67,21 +19,20 @@ if TYPE_CHECKING: if HAS_NUMPY: from .compat import np - Scalar = Union[ScalarProtocol, float, int, Decimal, Fraction, np.number[Any]] - Array = Union[np.ndarray[Any, Any]] + Scalar = Union[float, int, Decimal, Fraction, np.number[Any]] + Array = np.ndarray[Any, Any] else: - Scalar = Union[ScalarProtocol, float, int, Decimal, Fraction] - Array = ArrayProtocol - + Scalar = Union[float, int, Decimal, Fraction] + Array: TypeAlias = Never # TODO: Change when Python 3.10 becomes minimal version. -Magnitude = Union[ScalarProtocol, ArrayProtocol] +Magnitude = Union[Scalar, Array] UnitLike = Union[str, dict[str, Scalar], "UnitsContainer", "Unit"] QuantityOrUnitLike = Union["Quantity", UnitLike] -Shape = tuple[int] +Shape = tuple[int, ...] S = TypeVar("S") diff --git a/pint/compat.py b/pint/compat.py index 727ff99..f699c51 100644 --- a/pint/compat.py +++ b/pint/compat.py @@ -10,6 +10,7 @@ from __future__ import annotations +import sys import math import tokenize from decimal import Decimal @@ -20,15 +21,22 @@ from collections.abc import Mapping from typing import Any, NoReturn, Callable from collections.abc import Generator, Iterable -try: - from typing import TypeAlias # noqa -except ImportError: - from typing_extensions import TypeAlias # noqa +if sys.version_info >= (3, 10): + pass +else: + pass -try: - from typing import Self # noqa -except ImportError: - from typing_extensions import Self # noqa + +if sys.version_info >= (3, 11): + pass +else: + pass + + +if sys.version_info >= (3, 11): + pass +else: + pass def missing_dependency( diff --git a/pint/delegates/txt_defparser/context.py b/pint/delegates/txt_defparser/context.py index ce9fc9b..6be5171 100644 --- a/pint/delegates/txt_defparser/context.py +++ b/pint/delegates/txt_defparser/context.py @@ -89,7 +89,7 @@ class BeginContext(PintParsedStatement): ) name: str - aliases: tuple[str] + aliases: tuple[str, ...] defaults: dict[str, numbers.Number] @classmethod @@ -189,7 +189,7 @@ class ContextDefinition( return self.opening.name @property - def aliases(self) -> tuple[str]: + def aliases(self) -> tuple[str, ...]: assert isinstance(self.opening, BeginContext) return self.opening.aliases @@ -199,7 +199,7 @@ class ContextDefinition( return self.opening.defaults @property - def relations(self) -> tuple[BidirectionalRelation | ForwardRelation]: + def relations(self) -> tuple[BidirectionalRelation | ForwardRelation, ...]: return tuple( r for r in self.body @@ -207,5 +207,5 @@ class ContextDefinition( ) @property - def redefinitions(self) -> tuple[plain.UnitDefinition]: + def redefinitions(self) -> tuple[plain.UnitDefinition, ...]: return tuple(r for r in self.body if isinstance(r, plain.UnitDefinition)) diff --git a/pint/delegates/txt_defparser/defaults.py b/pint/delegates/txt_defparser/defaults.py index 688d90f..b29be18 100644 --- a/pint/delegates/txt_defparser/defaults.py +++ b/pint/delegates/txt_defparser/defaults.py @@ -65,7 +65,7 @@ class DefaultsDefinition( ] @property - def _valid_fields(self) -> tuple[str]: + def _valid_fields(self) -> tuple[str, ...]: return tuple(f.name for f in fields(definitions.DefaultsDefinition)) def derive_definition(self) -> definitions.DefaultsDefinition: diff --git a/pint/delegates/txt_defparser/defparser.py b/pint/delegates/txt_defparser/defparser.py index 4acea2f..16f5a94 100644 --- a/pint/delegates/txt_defparser/defparser.py +++ b/pint/delegates/txt_defparser/defparser.py @@ -79,7 +79,7 @@ class _PintParser(fp.Parser[PintRootBlock, ParserConfig]): class DefParser: - skip_classes: tuple[type] = ( + skip_classes: tuple[type, ...] = ( fp.BOF, fp.BOR, fp.BOS, diff --git a/pint/delegates/txt_defparser/group.py b/pint/delegates/txt_defparser/group.py index e96d44b..851e685 100644 --- a/pint/delegates/txt_defparser/group.py +++ b/pint/delegates/txt_defparser/group.py @@ -109,10 +109,10 @@ class GroupDefinition( return self.opening.name @property - def using_group_names(self) -> tuple[str]: + def using_group_names(self) -> tuple[str, ...]: assert isinstance(self.opening, BeginGroup) return self.opening.using_group_names @property - def definitions(self) -> tuple[plain.UnitDefinition]: + def definitions(self) -> tuple[plain.UnitDefinition, ...]: return tuple(el for el in self.body if isinstance(el, plain.UnitDefinition)) diff --git a/pint/delegates/txt_defparser/system.py b/pint/delegates/txt_defparser/system.py index 4efbb4d..7a65a36 100644 --- a/pint/delegates/txt_defparser/system.py +++ b/pint/delegates/txt_defparser/system.py @@ -110,10 +110,10 @@ class SystemDefinition( return self.opening.name @property - def using_group_names(self) -> tuple[str]: + def using_group_names(self) -> tuple[str, ...]: assert isinstance(self.opening, BeginSystem) return self.opening.using_group_names @property - def rules(self) -> tuple[BaseUnitRule]: + def rules(self) -> tuple[BaseUnitRule, ...]: return tuple(el for el in self.body if isinstance(el, BaseUnitRule)) diff --git a/pint/errors.py b/pint/errors.py index 6cebb21..391a5ec 100644 --- a/pint/errors.py +++ b/pint/errors.py @@ -134,7 +134,7 @@ class RedefinitionError(ValueError, PintError): class UndefinedUnitError(AttributeError, PintError): """Raised when the units are not defined in the unit registry.""" - unit_names: str | tuple[str] + unit_names: str | tuple[str, ...] def __str__(self): if isinstance(self.unit_names, str): diff --git a/pint/facets/context/definitions.py b/pint/facets/context/definitions.py index d2581d5..f63a6fc 100644 --- a/pint/facets/context/definitions.py +++ b/pint/facets/context/definitions.py @@ -93,10 +93,10 @@ class ContextDefinition(errors.WithDefErr): #: name of the context name: str #: other na - aliases: tuple[str] + aliases: tuple[str, ...] defaults: dict[str, numbers.Number] - relations: tuple[Relation] - redefinitions: tuple[UnitDefinition] + relations: tuple[Relation, ...] + redefinitions: tuple[UnitDefinition, ...] @property def variables(self) -> set[str]: diff --git a/pint/facets/context/objects.py b/pint/facets/context/objects.py index 9517821..c63fd8d 100644 --- a/pint/facets/context/objects.py +++ b/pint/facets/context/objects.py @@ -92,11 +92,11 @@ class Context: def __init__( self, name: str | None = None, - aliases: tuple[str] = tuple(), + aliases: tuple[str, ...] = tuple(), defaults: dict[str, Any] | None = None, ) -> None: self.name: str | None = name - self.aliases: tuple[str] = aliases + self.aliases: tuple[str, ...] = aliases #: Maps (src, dst) -> transformation function self.funcs: dict[SrcDst, Transformation] = {} @@ -242,10 +242,10 @@ class Context: self, ) -> tuple[ str | None, - tuple[str], + tuple[str, ...], frozenset[tuple[SrcDst, int]], frozenset[tuple[str, Any]], - tuple[Any], + tuple[Any, ...], ]: """Generate a unique hashable and comparable representation of self, which can be used as a key in a dict. This class cannot define ``__hash__`` because it is @@ -324,7 +324,7 @@ class ContextChain(ChainMap[SrcDst, Context]): """ return self[(src, dst)].transform(src, dst, registry, value) - def hashable(self) -> tuple[Any]: + def hashable(self) -> tuple[Any, ...]: """Generate a unique hashable and comparable representation of self, which can be used as a key in a dict. This class cannot define ``__hash__`` because it is mutable, and the Python interpreter does cache the output of ``__hash__``. diff --git a/pint/facets/group/definitions.py b/pint/facets/group/definitions.py index 2f34750..f1ee0bc 100644 --- a/pint/facets/group/definitions.py +++ b/pint/facets/group/definitions.py @@ -23,9 +23,9 @@ class GroupDefinition(errors.WithDefErr): #: name of the group name: str #: unit groups that will be included within the group - using_group_names: tuple[str] + using_group_names: tuple[str, ...] #: definitions for the units existing within the group - definitions: tuple[plain.UnitDefinition] + definitions: tuple[plain.UnitDefinition, ...] @classmethod def from_lines( @@ -42,7 +42,7 @@ class GroupDefinition(errors.WithDefErr): return definition @property - def unit_names(self) -> tuple[str]: + def unit_names(self) -> tuple[str, ...]: return tuple(el.name for el in self.definitions) def __post_init__(self) -> None: diff --git a/pint/facets/plain/definitions.py b/pint/facets/plain/definitions.py index 4b352e7..5fa822c 100644 --- a/pint/facets/plain/definitions.py +++ b/pint/facets/plain/definitions.py @@ -120,7 +120,7 @@ class UnitDefinition(NamedDefinition, errors.WithDefErr): #: canonical symbol defined_symbol: str | None #: additional names for the same unit - aliases: tuple[str] + aliases: tuple[str, ...] #: A functiont that converts a value in these units into the reference units # TODO: this has changed as converter is now annotated as converter. # Briefly, in several places converter attributes like as_multiplicative were diff --git a/pint/facets/plain/quantity.py b/pint/facets/plain/quantity.py index 6098edb..2f3de43 100644 --- a/pint/facets/plain/quantity.py +++ b/pint/facets/plain/quantity.py @@ -394,7 +394,7 @@ class PlainQuantity(Generic[MagnitudeT], PrettyIPython, SharedRegistryObject): def from_tuple(cls, tup): return cls(tup[0], cls._REGISTRY.UnitsContainer(tup[1])) - def to_tuple(self) -> tuple[MagnitudeT, tuple[tuple[str]]]: + def to_tuple(self) -> tuple[MagnitudeT, tuple[tuple[str, ...]]]: return self.m, tuple(self._units.items()) def compatible_units(self, *contexts): diff --git a/pint/facets/plain/registry.py b/pint/facets/plain/registry.py index c0264de..3b26342 100644 --- a/pint/facets/plain/registry.py +++ b/pint/facets/plain/registry.py @@ -29,6 +29,7 @@ from typing import ( TypeVar, Union, Generic, + Generator, ) from collections.abc import Iterable, Iterator @@ -1008,7 +1009,7 @@ class GenericPlainRegistry(Generic[QuantityT, UnitT], metaclass=RegistryMeta): def parse_unit_name( self, unit_name: str, case_sensitive: bool | None = None - ) -> tuple[tuple[str, str, str]]: + ) -> tuple[tuple[str, str, str], ...]: """Parse a unit to identify prefix, unit name and suffix by walking the list of prefix and suffix. In case of equivalent combinations (e.g. ('kilo', 'gram', '') and @@ -1033,7 +1034,7 @@ class GenericPlainRegistry(Generic[QuantityT, UnitT], metaclass=RegistryMeta): def _parse_unit_name( self, unit_name: str, case_sensitive: bool | None = None - ) -> Iterator[tuple[str, str, str]]: + ) -> Generator[tuple[str, str, str], None, None]: """Helper of parse_unit_name.""" case_sensitive = ( self.case_sensitive if case_sensitive is None else case_sensitive diff --git a/pint/facets/system/definitions.py b/pint/facets/system/definitions.py index eb582f3..c334e9a 100644 --- a/pint/facets/system/definitions.py +++ b/pint/facets/system/definitions.py @@ -39,9 +39,9 @@ class SystemDefinition(errors.WithDefErr): #: name of the system name: str #: unit groups that will be included within the system - using_group_names: tuple[str] + using_group_names: tuple[str, ...] #: rules to define new base unit within the system. - rules: tuple[BaseUnitRule] + rules: tuple[BaseUnitRule, ...] @classmethod def from_lines( @@ -59,7 +59,7 @@ class SystemDefinition(errors.WithDefErr): return definition @property - def unit_replacements(self) -> tuple[tuple[str, str | None]]: + def unit_replacements(self) -> tuple[tuple[str, str | None], ...]: # TODO: check if None can be dropped. return tuple((el.new_unit_name, el.old_unit_name) for el in self.rules) diff --git a/pint/formatting.py b/pint/formatting.py index 28adf25..1002aa6 100644 --- a/pint/formatting.py +++ b/pint/formatting.py @@ -21,6 +21,7 @@ from .babel_names import _babel_lengths, _babel_units from .compat import babel_parse, HAS_BABEL if TYPE_CHECKING: + from .registry import UnitRegistry from .util import ItMatrix, UnitsContainer if HAS_BABEL: @@ -30,8 +31,16 @@ if TYPE_CHECKING: else: Locale = TypeVar("Locale") + __JOIN_REG_EXP = re.compile(r"{\d*}") +FORMATTER = Callable[ + [ + Any, + ], + str, +] + def _join(fmt: str, iterable: Iterable[Any]) -> str: """Join an iterable with the format specified in fmt. @@ -178,7 +187,7 @@ def register_unit_format(name: str): @register_unit_format("P") -def format_pretty(unit: UnitsContainer, registry, **options) -> str: +def format_pretty(unit: UnitsContainer, registry: UnitRegistry, **options) -> str: return formatter( unit.items(), as_ratio=True, @@ -209,7 +218,7 @@ def latex_escape(string: str) -> str: @register_unit_format("L") -def format_latex(unit: UnitsContainer, registry, **options) -> str: +def format_latex(unit: UnitsContainer, registry: UnitRegistry, **options) -> str: preprocessed = {rf"\mathrm{{{latex_escape(u)}}}": p for u, p in unit.items()} formatted = formatter( preprocessed.items(), @@ -225,7 +234,9 @@ def format_latex(unit: UnitsContainer, registry, **options) -> str: @register_unit_format("Lx") -def format_latex_siunitx(unit: UnitsContainer, registry, **options) -> str: +def format_latex_siunitx( + unit: UnitsContainer, registry: UnitRegistry, **options +) -> str: if registry is None: raise ValueError( "Can't format as siunitx without a registry." @@ -239,7 +250,7 @@ def format_latex_siunitx(unit: UnitsContainer, registry, **options) -> str: @register_unit_format("H") -def format_html(unit: UnitsContainer, registry, **options) -> str: +def format_html(unit: UnitsContainer, registry: UnitRegistry, **options) -> str: return formatter( unit.items(), as_ratio=True, @@ -253,7 +264,7 @@ def format_html(unit: UnitsContainer, registry, **options) -> str: @register_unit_format("D") -def format_default(unit: UnitsContainer, registry, **options) -> str: +def format_default(unit: UnitsContainer, registry: UnitRegistry, **options) -> str: return formatter( unit.items(), as_ratio=True, @@ -267,7 +278,7 @@ def format_default(unit: UnitsContainer, registry, **options) -> str: @register_unit_format("C") -def format_compact(unit: UnitsContainer, registry, **options) -> str: +def format_compact(unit: UnitsContainer, registry: UnitRegistry, **options) -> str: return formatter( unit.items(), as_ratio=True, @@ -288,7 +299,7 @@ def formatter( division_fmt: str = " / ", power_fmt: str = "{} ** {}", parentheses_fmt: str = "({0})", - exp_call=lambda x: f"{x:n}", + exp_call: FORMATTER = "{:n}".format, locale: str | None = None, babel_length: str = "long", babel_plural_form: str = "one", @@ -548,12 +559,12 @@ def split_format( return mspec, uspec -def vector_to_latex(vec: Iterable[Any], fmtfun=lambda x: format(x, ".2f")) -> str: +def vector_to_latex(vec: Iterable[Any], fmtfun: FORMATTER = ".2f".format) -> str: return matrix_to_latex([vec], fmtfun) -def matrix_to_latex(matrix: ItMatrix, fmtfun=lambda x: format(x, ".2f")) -> str: - ret = [] +def matrix_to_latex(matrix: ItMatrix, fmtfun: FORMATTER = ".2f".format) -> str: + ret: list[str] = [] for row in matrix: ret += [" & ".join(fmtfun(f) for f in row)] @@ -562,11 +573,10 @@ def matrix_to_latex(matrix: ItMatrix, fmtfun=lambda x: format(x, ".2f")) -> str: def ndarray_to_latex_parts( - ndarr, fmtfun=lambda x: format(x, ".2f"), dim: tuple[int] = tuple() + ndarr, fmtfun: FORMATTER = ".2f".format, dim: tuple[int, ...] = tuple() ): if isinstance(fmtfun, str): - fmt = fmtfun - fmtfun = lambda x: format(x, fmt) + fmtfun = fmtfun.format if ndarr.ndim == 0: _ndarr = ndarr.reshape(1) @@ -589,6 +599,6 @@ def ndarray_to_latex_parts( def ndarray_to_latex( - ndarr, fmtfun=lambda x: format(x, ".2f"), dim: tuple[int] = tuple() + ndarr, fmtfun: FORMATTER = ".2f".format, dim: tuple[int, ...] = tuple() ) -> str: return "\n".join(ndarray_to_latex_parts(ndarr, fmtfun, dim)) |