summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHernan Grecco <hgrecco@gmail.com>2023-05-09 19:45:34 -0300
committerHernan Grecco <hgrecco@gmail.com>2023-05-09 19:45:34 -0300
commite5c8b03a02e650134d6139ad38305797a2c962c8 (patch)
treedd74d796f80994efe3741cc20763cc708f97a447
parent10ac784342b2503a4f1b153ba2cbc4be72f75122 (diff)
downloadpint-e5c8b03a02e650134d6139ad38305797a2c962c8.tar.gz
Typing related fixes
-rw-r--r--pint/_typing.py63
-rw-r--r--pint/compat.py24
-rw-r--r--pint/delegates/txt_defparser/context.py8
-rw-r--r--pint/delegates/txt_defparser/defaults.py2
-rw-r--r--pint/delegates/txt_defparser/defparser.py2
-rw-r--r--pint/delegates/txt_defparser/group.py4
-rw-r--r--pint/delegates/txt_defparser/system.py4
-rw-r--r--pint/errors.py2
-rw-r--r--pint/facets/context/definitions.py6
-rw-r--r--pint/facets/context/objects.py10
-rw-r--r--pint/facets/group/definitions.py6
-rw-r--r--pint/facets/plain/definitions.py2
-rw-r--r--pint/facets/plain/quantity.py2
-rw-r--r--pint/facets/plain/registry.py5
-rw-r--r--pint/facets/system/definitions.py6
-rw-r--r--pint/formatting.py38
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))