diff options
author | Hernan Grecco <hgrecco@gmail.com> | 2023-05-14 18:46:01 -0300 |
---|---|---|
committer | Hernan Grecco <hgrecco@gmail.com> | 2023-05-14 18:46:01 -0300 |
commit | 499cce40459bfd8cdadbad46ad2e1139f4f873fe (patch) | |
tree | 4bd86af3bb6e4d3cc9f5fe1e9e55e83a3035fea0 | |
parent | aaac228fbdb2fc0d9f0f5431efc2252e3f9bbb80 (diff) | |
download | pint-499cce40459bfd8cdadbad46ad2e1139f4f873fe.tar.gz |
Python's 3.9 compatible typing annotations
26 files changed, 167 insertions, 136 deletions
diff --git a/pint/_typing.py b/pint/_typing.py index 25263da..7a67efc 100644 --- a/pint/_typing.py +++ b/pint/_typing.py @@ -19,10 +19,10 @@ if TYPE_CHECKING: if HAS_NUMPY: from .compat import np - Scalar = Union[float, int, Decimal, Fraction, np.number[Any]] + Scalar: TypeAlias = Union[float, int, Decimal, Fraction, np.number[Any]] Array = np.ndarray[Any, Any] else: - Scalar = Union[float, int, Decimal, Fraction] + Scalar: TypeAlias = Union[float, int, Decimal, Fraction] Array: TypeAlias = Never # TODO: Change when Python 3.10 becomes minimal version. diff --git a/pint/compat.py b/pint/compat.py index f4ffeae..6be906f 100644 --- a/pint/compat.py +++ b/pint/compat.py @@ -18,7 +18,7 @@ from importlib import import_module from io import BytesIO from numbers import Number from collections.abc import Mapping -from typing import Any, NoReturn, Callable +from typing import Any, NoReturn, Callable, Optional, Union from collections.abc import Generator, Iterable @@ -41,7 +41,7 @@ else: def missing_dependency( - package: str, display_name: str | None = None + package: str, display_name: Optional[str] = None ) -> Callable[..., NoReturn]: """Return a helper function that raises an exception when used. @@ -225,7 +225,7 @@ upcast_type_names = ( ) #: Map type name to the actual type (for upcast types). -upcast_type_map: Mapping[str, type | None] = {k: None for k in upcast_type_names} +upcast_type_map: Mapping[str, Optional[type]] = {k: None for k in upcast_type_names} def fully_qualified_name(t: type) -> str: @@ -286,7 +286,7 @@ def is_duck_array(obj: type) -> bool: return is_duck_array_type(type(obj)) -def eq(lhs: Any, rhs: Any, check_all: bool) -> bool | Iterable[bool]: +def eq(lhs: Any, rhs: Any, check_all: bool) -> Union[bool, Iterable[bool]]: """Comparison of scalars and arrays. Parameters @@ -309,7 +309,7 @@ def eq(lhs: Any, rhs: Any, check_all: bool) -> bool | Iterable[bool]: return out -def isnan(obj: Any, check_all: bool) -> bool | Iterable[bool]: +def isnan(obj: Any, check_all: bool) -> Union[bool, Iterable[bool]]: """Test for NaN or NaT. Parameters @@ -342,7 +342,7 @@ def isnan(obj: Any, check_all: bool) -> bool | Iterable[bool]: return False -def zero_or_nan(obj: Any, check_all: bool) -> bool | Iterable[bool]: +def zero_or_nan(obj: Any, check_all: bool) -> Union[bool, Iterable[bool]]: """Test if obj is zero, NaN, or NaT. Parameters diff --git a/pint/converters.py b/pint/converters.py index 822b8a0..daf25bc 100644 --- a/pint/converters.py +++ b/pint/converters.py @@ -13,7 +13,7 @@ from __future__ import annotations from dataclasses import dataclass from dataclasses import fields as dc_fields -from typing import Any +from typing import Any, Optional from ._typing import Magnitude @@ -53,7 +53,7 @@ class Converter: return frozenset(p.name for p in dc_fields(new_cls)) @classmethod - def preprocess_kwargs(cls, **kwargs: Any) -> dict[str, Any] | None: + def preprocess_kwargs(cls, **kwargs: Any) -> Optional[dict[str, Any]]: return None @classmethod diff --git a/pint/delegates/txt_defparser/context.py b/pint/delegates/txt_defparser/context.py index 6be5171..5ede7b4 100644 --- a/pint/delegates/txt_defparser/context.py +++ b/pint/delegates/txt_defparser/context.py @@ -19,6 +19,7 @@ from __future__ import annotations import numbers import re import typing as ty +from typing import Optional, Union from dataclasses import dataclass from ..._vendor import flexparser as fp @@ -27,12 +28,12 @@ from ..base_defparser import ParserConfig, PintParsedStatement from . import block, common, plain # TODO check syntax -T = ty.TypeVar("T", bound="ForwardRelation | BidirectionalRelation") +T = ty.TypeVar("T", bound="Union[ForwardRelation, BidirectionalRelation]") def _from_string_and_context_sep( cls: type[T], s: str, config: ParserConfig, separator: str -) -> T | None: +) -> Optional[T]: if separator not in s: return None if ":" not in s: @@ -199,7 +200,7 @@ class ContextDefinition( return self.opening.defaults @property - def relations(self) -> tuple[BidirectionalRelation | ForwardRelation, ...]: + def relations(self) -> tuple[Union[BidirectionalRelation, ForwardRelation], ...]: return tuple( r for r in self.body diff --git a/pint/delegates/txt_defparser/defparser.py b/pint/delegates/txt_defparser/defparser.py index 16f5a94..a5ccb08 100644 --- a/pint/delegates/txt_defparser/defparser.py +++ b/pint/delegates/txt_defparser/defparser.py @@ -2,6 +2,7 @@ from __future__ import annotations import pathlib import typing as ty +from typing import Optional, Union from ..._vendor import flexcache as fc from ..._vendor import flexparser as fp @@ -130,7 +131,9 @@ class DefParser: else: yield stmt - def parse_file(self, filename: pathlib.Path | str, cfg: ParserConfig | None = None): + def parse_file( + self, filename: Union[pathlib.Path, str], cfg: Optional[ParserConfig] = None + ): return fp.parse( filename, _PintParser, @@ -138,7 +141,7 @@ class DefParser: diskcache=self._diskcache, ) - def parse_string(self, content: str, cfg: ParserConfig | None = None): + def parse_string(self, content: str, cfg: Optional[ParserConfig] = None): return fp.parse_bytes( content.encode("utf-8"), _PintParser, diff --git a/pint/errors.py b/pint/errors.py index 391a5ec..8041c18 100644 --- a/pint/errors.py +++ b/pint/errors.py @@ -10,6 +10,7 @@ from __future__ import annotations +from typing import Union import typing as ty from dataclasses import dataclass, fields @@ -134,7 +135,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: Union[str, tuple[str, ...]] def __str__(self): if isinstance(self.unit_names, str): diff --git a/pint/facets/context/objects.py b/pint/facets/context/objects.py index c63fd8d..4ab2f1d 100644 --- a/pint/facets/context/objects.py +++ b/pint/facets/context/objects.py @@ -10,7 +10,7 @@ from __future__ import annotations import weakref from collections import ChainMap, defaultdict -from typing import Any, Callable, Protocol, Generic +from typing import Any, Callable, Protocol, Generic, Optional from collections.abc import Iterable from ...facets.plain import UnitDefinition, PlainQuantity, PlainUnit, MagnitudeT @@ -91,11 +91,11 @@ class Context: def __init__( self, - name: str | None = None, + name: Optional[str] = None, aliases: tuple[str, ...] = tuple(), - defaults: dict[str, Any] | None = None, + defaults: Optional[dict[str, Any]] = None, ) -> None: - self.name: str | None = name + self.name: Optional[str] = name self.aliases: tuple[str, ...] = aliases #: Maps (src, dst) -> transformation function @@ -150,7 +150,7 @@ class Context: def from_lines( cls, lines: Iterable[str], - to_base_func: ToBaseFunc | None = None, + to_base_func: Optional[ToBaseFunc] = None, non_int_type: type = float, ) -> Context: context_definition = ContextDefinition.from_lines(lines, non_int_type) @@ -162,7 +162,7 @@ class Context: @classmethod def from_definition( - cls, cd: ContextDefinition, to_base_func: ToBaseFunc | None = None + cls, cd: ContextDefinition, to_base_func: Optional[ToBaseFunc] = None ) -> Context: ctx = cls(cd.name, cd.aliases, cd.defaults) @@ -241,7 +241,7 @@ class Context: def hashable( self, ) -> tuple[ - str | None, + Optional[str], tuple[str, ...], frozenset[tuple[SrcDst, int]], frozenset[tuple[str, Any]], @@ -273,7 +273,7 @@ class ContextChain(ChainMap[SrcDst, Context]): super().__init__() self.contexts: list[Context] = [] self.maps.clear() # Remove default empty map - self._graph: dict[SrcDst, set[UnitsContainer]] | None = None + self._graph: Optional[dict[SrcDst, set[UnitsContainer]]] = None def insert_contexts(self, *contexts: Context): """Insert one or more contexts in reversed order the chained map. @@ -287,7 +287,7 @@ class ContextChain(ChainMap[SrcDst, Context]): self.maps = [ctx.relation_to_context for ctx in reversed(contexts)] + self.maps self._graph = None - def remove_contexts(self, n: int | None = None): + def remove_contexts(self, n: Optional[int] = None): """Remove the last n inserted contexts from the chain. Parameters diff --git a/pint/facets/context/registry.py b/pint/facets/context/registry.py index 746e79c..85682d1 100644 --- a/pint/facets/context/registry.py +++ b/pint/facets/context/registry.py @@ -11,7 +11,7 @@ from __future__ import annotations import functools from collections import ChainMap from contextlib import contextmanager -from typing import Any, Callable, Generator, Generic +from typing import Any, Callable, Generator, Generic, Optional, Union from ...compat import TypeAlias from ..._typing import F, Magnitude @@ -74,7 +74,7 @@ class GenericContextRegistry( super()._register_definition_adders() self._register_adder(ContextDefinition, self.add_context) - def add_context(self, context: objects.Context | ContextDefinition) -> None: + def add_context(self, context: Union[objects.Context, ContextDefinition]) -> None: """Add a context object to the registry. The context will be accessible by its name and aliases. @@ -197,7 +197,7 @@ class GenericContextRegistry( self.define(definition) def enable_contexts( - self, *names_or_contexts: str | objects.Context, **kwargs: Any + self, *names_or_contexts: Union[str, objects.Context], **kwargs: Any ) -> None: """Enable contexts provided by name or by object. @@ -244,7 +244,7 @@ class GenericContextRegistry( self._active_ctx.insert_contexts(*contexts) self._switch_context_cache_and_units() - def disable_contexts(self, n: int | None = None) -> None: + def disable_contexts(self, n: Optional[int] = None) -> None: """Disable the last n enabled contexts. Parameters @@ -403,7 +403,7 @@ class GenericContextRegistry( return super()._convert(value, src, dst, inplace) def _get_compatible_units( - self, input_units: UnitsContainer, group_or_system: str | None = None + self, input_units: UnitsContainer, group_or_system: Optional[str] = None ): src_dim = self._get_dimensionality(input_units) diff --git a/pint/facets/group/definitions.py b/pint/facets/group/definitions.py index f1ee0bc..0a22b50 100644 --- a/pint/facets/group/definitions.py +++ b/pint/facets/group/definitions.py @@ -10,6 +10,7 @@ from __future__ import annotations from collections.abc import Iterable from dataclasses import dataclass +from typing import Optional from ...compat import Self from ... import errors @@ -30,7 +31,7 @@ class GroupDefinition(errors.WithDefErr): @classmethod def from_lines( cls: type[Self], lines: Iterable[str], non_int_type: type - ) -> Self | None: + ) -> Optional[Self]: # TODO: this is to keep it backwards compatible from ...delegates import ParserConfig, txt_defparser diff --git a/pint/facets/group/objects.py b/pint/facets/group/objects.py index 64d91c1..dbd7ecf 100644 --- a/pint/facets/group/objects.py +++ b/pint/facets/group/objects.py @@ -8,7 +8,7 @@ from __future__ import annotations -from typing import Callable, Any, TYPE_CHECKING, Generic +from typing import Callable, Any, TYPE_CHECKING, Generic, Optional from collections.abc import Generator, Iterable from ...util import SharedRegistryObject, getattr_maybe_raise @@ -81,7 +81,7 @@ class Group(SharedRegistryObject): #: A cache of the included units. #: None indicates that the cache has been invalidated. - self._computed_members: frozenset[str] | None = None + self._computed_members: Optional[frozenset[str]] = None @property def members(self) -> frozenset[str]: @@ -195,7 +195,9 @@ class Group(SharedRegistryObject): @classmethod def from_definition( - cls, group_definition: GroupDefinition, add_unit_func: AddUnitFunc | None = None + cls, + group_definition: GroupDefinition, + add_unit_func: Optional[AddUnitFunc] = None, ) -> Group: grp = cls(group_definition.name) diff --git a/pint/facets/group/registry.py b/pint/facets/group/registry.py index f130e61..da068c5 100644 --- a/pint/facets/group/registry.py +++ b/pint/facets/group/registry.py @@ -8,7 +8,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Generic, Any +from typing import TYPE_CHECKING, Generic, Any, Optional from ...compat import TypeAlias from ... import errors @@ -47,7 +47,6 @@ class GenericGroupRegistry( def __init__(self, **kwargs): super().__init__(**kwargs) #: Map group name to group. - #: :type: dict[ str | Group] self._groups: dict[str, objects.Group] = {} self._groups["root"] = self.Group("root") @@ -122,7 +121,7 @@ class GenericGroupRegistry( return self.Group(name) def get_compatible_units( - self, input_units: UnitsContainer, group: str | None = None + self, input_units: UnitsContainer, group: Optional[str] = None ) -> frozenset[Unit]: """ """ if group is None: @@ -135,7 +134,7 @@ class GenericGroupRegistry( return frozenset(self.Unit(eq) for eq in equiv) def _get_compatible_units( - self, input_units: UnitsContainer, group: str | None = None + self, input_units: UnitsContainer, group: Optional[str] = None ) -> frozenset[str]: ret = super()._get_compatible_units(input_units) diff --git a/pint/facets/nonmultiplicative/objects.py b/pint/facets/nonmultiplicative/objects.py index 8b944b1..8ebe8f8 100644 --- a/pint/facets/nonmultiplicative/objects.py +++ b/pint/facets/nonmultiplicative/objects.py @@ -8,7 +8,7 @@ from __future__ import annotations -from typing import Generic +from typing import Generic, Optional from ..plain import PlainQuantity, PlainUnit, MagnitudeT @@ -42,7 +42,7 @@ class NonMultiplicativeQuantity(Generic[MagnitudeT], PlainQuantity[MagnitudeT]): self._get_unit_definition(d).reference == offset_unit_dim for d in deltas ) - def _ok_for_muldiv(self, no_offset_units: int | None = None) -> bool: + def _ok_for_muldiv(self, no_offset_units: Optional[int] = None) -> bool: """Checks if PlainQuantity object can be multiplied or divided""" is_ok = True diff --git a/pint/facets/nonmultiplicative/registry.py b/pint/facets/nonmultiplicative/registry.py index 505406c..7d783de 100644 --- a/pint/facets/nonmultiplicative/registry.py +++ b/pint/facets/nonmultiplicative/registry.py @@ -8,7 +8,7 @@ from __future__ import annotations -from typing import Any, TypeVar, Generic +from typing import Any, TypeVar, Generic, Optional from ...compat import TypeAlias from ...errors import DimensionalityError, UndefinedUnitError @@ -60,8 +60,8 @@ class GenericNonMultiplicativeRegistry( def _parse_units( self, input_string: str, - as_delta: bool | None = None, - case_sensitive: bool | None = None, + as_delta: Optional[bool] = None, + case_sensitive: Optional[bool] = None, ) -> UnitsContainer: """ """ if as_delta is None: @@ -136,7 +136,7 @@ class GenericNonMultiplicativeRegistry( except KeyError: raise UndefinedUnitError(unit_name) - def _validate_and_extract(self, units: UnitsContainer) -> str | None: + def _validate_and_extract(self, units: UnitsContainer) -> Optional[str]: """Used to check if a given units is suitable for a simple conversion. diff --git a/pint/facets/plain/definitions.py b/pint/facets/plain/definitions.py index 5fa822c..44bf298 100644 --- a/pint/facets/plain/definitions.py +++ b/pint/facets/plain/definitions.py @@ -13,7 +13,7 @@ import numbers import typing as ty from dataclasses import dataclass from functools import cached_property -from typing import Any +from typing import Any, Optional from ..._typing import Magnitude from ... import errors @@ -81,7 +81,7 @@ class PrefixDefinition(NamedDefinition, errors.WithDefErr): #: scaling value for this prefix value: numbers.Number #: canonical symbol - defined_symbol: str | None = "" + defined_symbol: Optional[str] = "" #: additional names for the same prefix aliases: ty.Tuple[str, ...] = () @@ -118,7 +118,7 @@ class UnitDefinition(NamedDefinition, errors.WithDefErr): """Definition of a unit.""" #: canonical symbol - defined_symbol: str | None + defined_symbol: Optional[str] #: additional names for the same unit aliases: tuple[str, ...] #: A functiont that converts a value in these units into the reference units @@ -126,15 +126,15 @@ class UnitDefinition(NamedDefinition, errors.WithDefErr): # Briefly, in several places converter attributes like as_multiplicative were # accesed. So having a generic function is a no go. # I guess this was never used as errors where not raised. - converter: Converter | None + converter: Optional[Converter] #: Reference units. - reference: UnitsContainer | None + reference: Optional[UnitsContainer] def __post_init__(self): if not errors.is_valid_unit_name(self.name): raise self.def_err(errors.MSG_INVALID_UNIT_NAME) - # TODO: check why reference: UnitsContainer | None + # TODO: check why reference: Optional[UnitsContainer] assert isinstance(self.reference, UnitsContainer) if not any(map(errors.is_dim, self.reference.keys())): diff --git a/pint/facets/plain/qto.py b/pint/facets/plain/qto.py index 72b8157..0508e9a 100644 --- a/pint/facets/plain/qto.py +++ b/pint/facets/plain/qto.py @@ -1,12 +1,13 @@ from __future__ import annotations -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Optional import bisect import math import numbers -from ...util import infer_base_unit import warnings + +from ...util import infer_base_unit from ...compat import ( mip_INF, mip_INTEGER, @@ -81,7 +82,7 @@ def to_reduced_units( def to_compact( - quantity: PlainQuantity, unit: UnitsContainer | None = None + quantity: PlainQuantity, unit: Optional[UnitsContainer] = None ) -> PlainQuantity: """ "Return PlainQuantity rescaled to compact, human-readable units. diff --git a/pint/facets/plain/quantity.py b/pint/facets/plain/quantity.py index c06d02f..5841a9a 100644 --- a/pint/facets/plain/quantity.py +++ b/pint/facets/plain/quantity.py @@ -14,7 +14,16 @@ import datetime import locale import numbers import operator -from typing import TYPE_CHECKING, Any, Callable, overload, Generic, TypeVar +from typing import ( + TYPE_CHECKING, + Any, + Callable, + overload, + Generic, + TypeVar, + Optional, + Union, +) from collections.abc import Iterator, Sequence from ..._typing import UnitLike, QuantityOrUnitLike, Magnitude, Scalar @@ -155,23 +164,25 @@ class PlainQuantity(Generic[MagnitudeT], PrettyIPython, SharedRegistryObject): @overload def __new__( - cls, value: MagnitudeT, units: UnitLike | None = None + cls, value: MagnitudeT, units: Optional[UnitLike] = None ) -> PlainQuantity[MagnitudeT]: ... @overload - def __new__(cls, value: str, units: UnitLike | None = None) -> PlainQuantity[Any]: + def __new__( + cls, value: str, units: Optional[UnitLike] = None + ) -> PlainQuantity[Any]: ... @overload def __new__( # type: ignore[misc] - cls, value: Sequence[ScalarT], units: UnitLike | None = None + cls, value: Sequence[ScalarT], units: Optional[UnitLike] = None ) -> PlainQuantity[Any]: ... @overload def __new__( - cls, value: PlainQuantity[Any], units: UnitLike | None = None + cls, value: PlainQuantity[Any], units: Optional[UnitLike] = None ) -> PlainQuantity[Any]: ... @@ -311,7 +322,7 @@ class PlainQuantity(Generic[MagnitudeT], PrettyIPython, SharedRegistryObject): return not bool(tmp.dimensionality) - _dimensionality: UnitsContainerT | None = None + _dimensionality: Optional[UnitsContainerT] = None @property def dimensionality(self) -> UnitsContainerT: @@ -406,7 +417,7 @@ class PlainQuantity(Generic[MagnitudeT], PrettyIPython, SharedRegistryObject): return self._REGISTRY.get_compatible_units(self._units) def is_compatible_with( - self, other: Any, *contexts: str | Context, **ctx_kwargs: Any + self, other: Any, *contexts: Union[str, Context], **ctx_kwargs: Any ) -> bool: """check if the other object is compatible @@ -463,7 +474,7 @@ class PlainQuantity(Generic[MagnitudeT], PrettyIPython, SharedRegistryObject): ) def ito( - self, other: QuantityOrUnitLike | None = None, *contexts, **ctx_kwargs + self, other: Optional[QuantityOrUnitLike] = None, *contexts, **ctx_kwargs ) -> None: """Inplace rescale to different units. @@ -484,7 +495,7 @@ class PlainQuantity(Generic[MagnitudeT], PrettyIPython, SharedRegistryObject): return None def to( - self, other: QuantityOrUnitLike | None = None, *contexts, **ctx_kwargs + self, other: Optional[QuantityOrUnitLike] = None, *contexts, **ctx_kwargs ) -> PlainQuantity: """Return PlainQuantity rescaled to different units. @@ -1257,7 +1268,7 @@ class PlainQuantity(Generic[MagnitudeT], PrettyIPython, SharedRegistryObject): def __abs__(self) -> PlainQuantity[MagnitudeT]: return self.__class__(abs(self._magnitude), self._units) - def __round__(self, ndigits: int | None = 0) -> PlainQuantity[MagnitudeT]: + def __round__(self, ndigits: Optional[int] = 0) -> PlainQuantity[MagnitudeT]: return self.__class__(round(self._magnitude, ndigits=ndigits), self._units) def __pos__(self) -> PlainQuantity[MagnitudeT]: diff --git a/pint/facets/plain/registry.py b/pint/facets/plain/registry.py index 3b26342..a6d7a13 100644 --- a/pint/facets/plain/registry.py +++ b/pint/facets/plain/registry.py @@ -30,6 +30,7 @@ from typing import ( Union, Generic, Generator, + Optional, ) from collections.abc import Iterable, Iterator @@ -80,7 +81,7 @@ _BLOCK_RE = re.compile(r"[ (]") @functools.lru_cache -def pattern_to_regex(pattern: str | re.Pattern[str]) -> re.Pattern[str]: +def pattern_to_regex(pattern: Union[str, re.Pattern[str]]) -> re.Pattern[str]: # TODO: This has been changed during typing improvements. # if hasattr(pattern, "finditer"): if not isinstance(pattern, str): @@ -188,7 +189,7 @@ class GenericPlainRegistry(Generic[QuantityT, UnitT], metaclass=RegistryMeta): """ #: Babel.Locale instance or None - fmt_locale: Locale | None = None + fmt_locale: Optional[Locale] = None Quantity: type[QuantityT] Unit: type[UnitT] @@ -203,12 +204,12 @@ class GenericPlainRegistry(Generic[QuantityT, UnitT], metaclass=RegistryMeta): force_ndarray_like: bool = False, on_redefinition: str = "warn", auto_reduce_dimensions: bool = False, - preprocessors: list[PreprocessorType] | None = None, - fmt_locale: str | None = None, + preprocessors: Optional[list[PreprocessorType]] = None, + fmt_locale: Optional[str] = None, non_int_type: NON_INT_TYPE = float, case_sensitive: bool = True, - cache_folder: str | pathlib.Path | None = None, - separate_format_defaults: bool | None = None, + cache_folder: Optional[Union[str, pathlib.Path]] = None, + separate_format_defaults: Optional[bool] = None, mpl_formatter: str = "{:P}", ): #: Map a definition class to a adder methods. @@ -265,7 +266,7 @@ class GenericPlainRegistry(Generic[QuantityT, UnitT], metaclass=RegistryMeta): #: Map dimension name (string) to its definition (DimensionDefinition). self._dimensions: dict[ - str, DimensionDefinition | DerivedDimensionDefinition + str, Union[DimensionDefinition, DerivedDimensionDefinition] ] = {} #: Map unit name (string) to its definition (UnitDefinition). @@ -373,7 +374,7 @@ class GenericPlainRegistry(Generic[QuantityT, UnitT], metaclass=RegistryMeta): """ return iter(sorted(self._units.keys())) - def set_fmt_locale(self, loc: str | None) -> None: + def set_fmt_locale(self, loc: Optional[str]) -> None: """Change the locale used by default by `format_babel`. Parameters @@ -402,7 +403,7 @@ class GenericPlainRegistry(Generic[QuantityT, UnitT], metaclass=RegistryMeta): self.Measurement.default_format = value @property - def cache_folder(self) -> pathlib.Path | None: + def cache_folder(self) -> Optional[pathlib.Path]: if self._diskcache: return self._diskcache.cache_folder return None @@ -411,7 +412,7 @@ class GenericPlainRegistry(Generic[QuantityT, UnitT], metaclass=RegistryMeta): def non_int_type(self): return self._non_int_type - def define(self, definition: str | type) -> None: + def define(self, definition: Union[str, type]) -> None: """Add unit to the registry. Parameters @@ -453,7 +454,7 @@ class GenericPlainRegistry(Generic[QuantityT, UnitT], metaclass=RegistryMeta): self, definition: NamedDefinition, target_dict: dict[str, Any], - casei_target_dict: dict[str, Any] | None, + casei_target_dict: Optional[dict[str, Any]], ) -> None: """Helper function to store a definition in the internal dictionaries. It stores the definition under its name, symbol and aliases. @@ -479,7 +480,7 @@ class GenericPlainRegistry(Generic[QuantityT, UnitT], metaclass=RegistryMeta): key: str, value: NamedDefinition, target_dict: dict[str, Any], - casei_target_dict: dict[str, Any] | None, + casei_target_dict: Optional[dict[str, Any]], ) -> None: """Helper function to store a definition in the internal dictionaries. @@ -529,7 +530,7 @@ class GenericPlainRegistry(Generic[QuantityT, UnitT], metaclass=RegistryMeta): self._helper_adder(definition, self._units, self._units_casei) def load_definitions( - self, file: Iterable[str] | str | pathlib.Path, is_resource: bool = False + self, file: Union[Iterable[str], str, pathlib.Path], is_resource: bool = False ): """Add units and prefixes defined in a definition text file. @@ -600,7 +601,9 @@ class GenericPlainRegistry(Generic[QuantityT, UnitT], metaclass=RegistryMeta): logger.warning(f"Could not resolve {unit_name}: {exc!r}") return self._cache - def get_name(self, name_or_alias: str, case_sensitive: bool | None = None) -> str: + def get_name( + self, name_or_alias: str, case_sensitive: Optional[bool] = None + ) -> str: """Return the canonical name of a unit.""" if name_or_alias == "dimensionless": @@ -637,7 +640,9 @@ class GenericPlainRegistry(Generic[QuantityT, UnitT], metaclass=RegistryMeta): return unit_name - def get_symbol(self, name_or_alias: str, case_sensitive: bool | None = None) -> str: + def get_symbol( + self, name_or_alias: str, case_sensitive: Optional[bool] = None + ) -> str: """Return the preferred alias for a unit.""" candidates = self.parse_unit_name(name_or_alias, case_sensitive) if not candidates: @@ -666,7 +671,9 @@ class GenericPlainRegistry(Generic[QuantityT, UnitT], metaclass=RegistryMeta): return self._get_dimensionality(input_units) - def _get_dimensionality(self, input_units: UnitsContainer | None) -> UnitsContainer: + def _get_dimensionality( + self, input_units: Optional[UnitsContainer] + ) -> UnitsContainer: """Convert a UnitsContainer to plain dimensions.""" if not input_units: return self.UnitsContainer() @@ -801,7 +808,7 @@ class GenericPlainRegistry(Generic[QuantityT, UnitT], metaclass=RegistryMeta): except KeyError: pass - accumulators: dict[str | None, int] = defaultdict(int) + accumulators: dict[Optional[str], int] = defaultdict(int) accumulators[None] = 1 self._get_root_units_recurse(input_units, 1, accumulators) @@ -819,7 +826,10 @@ class GenericPlainRegistry(Generic[QuantityT, UnitT], metaclass=RegistryMeta): return factor, units def get_base_units( - self, input_units: UnitsContainer | str, check_nonmult: bool = True, system=None + self, + input_units: Union[UnitsContainer, str], + check_nonmult: bool = True, + system=None, ) -> tuple[Number, UnitT]: """Convert unit or dict of units to the plain units. @@ -849,7 +859,7 @@ class GenericPlainRegistry(Generic[QuantityT, UnitT], metaclass=RegistryMeta): # TODO: accumulators breaks typing list[int, dict[str, int]] # So we have changed the behavior here def _get_root_units_recurse( - self, ref: UnitsContainer, exp: Scalar, accumulators: dict[str | None, int] + self, ref: UnitsContainer, exp: Scalar, accumulators: dict[Optional[str], int] ) -> None: """ @@ -887,7 +897,7 @@ class GenericPlainRegistry(Generic[QuantityT, UnitT], metaclass=RegistryMeta): # TODO: remove context from here def is_compatible_with( - self, obj1: Any, obj2: Any, *contexts: str | Context, **ctx_kwargs + self, obj1: Any, obj2: Any, *contexts: Union[str, Context], **ctx_kwargs ) -> bool: """check if the other object is compatible @@ -1008,7 +1018,7 @@ class GenericPlainRegistry(Generic[QuantityT, UnitT], metaclass=RegistryMeta): return value def parse_unit_name( - self, unit_name: str, case_sensitive: bool | None = None + self, unit_name: str, case_sensitive: Optional[bool] = None ) -> tuple[tuple[str, str, str], ...]: """Parse a unit to identify prefix, unit name and suffix by walking the list of prefix and suffix. @@ -1033,7 +1043,7 @@ class GenericPlainRegistry(Generic[QuantityT, UnitT], metaclass=RegistryMeta): ) def _parse_unit_name( - self, unit_name: str, case_sensitive: bool | None = None + self, unit_name: str, case_sensitive: Optional[bool] = None ) -> Generator[tuple[str, str, str], None, None]: """Helper of parse_unit_name.""" case_sensitive = ( @@ -1087,8 +1097,8 @@ class GenericPlainRegistry(Generic[QuantityT, UnitT], metaclass=RegistryMeta): def parse_units( self, input_string: str, - as_delta: bool | None = None, - case_sensitive: bool | None = None, + as_delta: Optional[bool] = None, + case_sensitive: Optional[bool] = None, ) -> UnitT: """Parse a units expression and returns a UnitContainer with the canonical names. @@ -1121,7 +1131,7 @@ class GenericPlainRegistry(Generic[QuantityT, UnitT], metaclass=RegistryMeta): self, input_string: str, as_delta: bool = True, - case_sensitive: bool | None = None, + case_sensitive: Optional[bool] = None, ) -> UnitsContainer: """Parse a units expression and returns a UnitContainer with the canonical names. @@ -1165,7 +1175,7 @@ class GenericPlainRegistry(Generic[QuantityT, UnitT], metaclass=RegistryMeta): def _eval_token( self, token: TokenInfo, - case_sensitive: bool | None = None, + case_sensitive: Optional[bool] = None, **values: QuantityArgument, ): """Evaluate a single token using the following rules: @@ -1215,9 +1225,9 @@ class GenericPlainRegistry(Generic[QuantityT, UnitT], metaclass=RegistryMeta): self, input_string: str, pattern: str, - case_sensitive: bool | None = None, + case_sensitive: Optional[bool] = None, many: bool = False, - ) -> list[str] | str | None: + ) -> Optional[Union[list[str], str]]: """Parse a string with a given regex pattern and returns result. Parameters @@ -1266,7 +1276,7 @@ class GenericPlainRegistry(Generic[QuantityT, UnitT], metaclass=RegistryMeta): def parse_expression( self: Self, input_string: str, - case_sensitive: bool | None = None, + case_sensitive: Optional[bool] = None, **values: QuantityArgument, ) -> QuantityT: """Parse a mathematical expression including units and return a quantity object. diff --git a/pint/facets/plain/unit.py b/pint/facets/plain/unit.py index 64a7d3c..4c5c04a 100644 --- a/pint/facets/plain/unit.py +++ b/pint/facets/plain/unit.py @@ -12,7 +12,7 @@ import copy import locale import operator from numbers import Number -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, Union from ..._typing import UnitLike from ...compat import NUMERIC_TYPES @@ -96,7 +96,7 @@ class PlainUnit(PrettyIPython, SharedRegistryObject): return self._REGISTRY.get_compatible_units(self) def is_compatible_with( - self, other: Any, *contexts: str | Context, **ctx_kwargs: Any + self, other: Any, *contexts: Union[str, Context], **ctx_kwargs: Any ) -> bool: """check if the other object is compatible diff --git a/pint/facets/system/definitions.py b/pint/facets/system/definitions.py index c334e9a..008abac 100644 --- a/pint/facets/system/definitions.py +++ b/pint/facets/system/definitions.py @@ -10,6 +10,7 @@ from __future__ import annotations from collections.abc import Iterable from dataclasses import dataclass +from typing import Optional from ...compat import Self from ... import errors @@ -24,7 +25,7 @@ class BaseUnitRule: new_unit_name: str #: name of the unit to be kicked out to make room for the new base uni #: If None, the current base unit with the same dimensionality will be used - old_unit_name: str | None = None + old_unit_name: Optional[str] = None # Instead of defining __post_init__ here, # it will be added to the container class @@ -46,7 +47,7 @@ class SystemDefinition(errors.WithDefErr): @classmethod def from_lines( cls: type[Self], lines: Iterable[str], non_int_type: type - ) -> Self | None: + ) -> Optional[Self]: # TODO: this is to keep it backwards compatible # TODO: check when is None returned. from ...delegates import ParserConfig, txt_defparser @@ -59,7 +60,7 @@ class SystemDefinition(errors.WithDefErr): return definition @property - def unit_replacements(self) -> tuple[tuple[str, str | None], ...]: + def unit_replacements(self) -> tuple[tuple[str, Optional[str]], ...]: # 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/facets/system/objects.py b/pint/facets/system/objects.py index cf6a24f..912094d 100644 --- a/pint/facets/system/objects.py +++ b/pint/facets/system/objects.py @@ -11,7 +11,7 @@ from __future__ import annotations import numbers -from typing import Any +from typing import Any, Optional from collections.abc import Iterable @@ -73,7 +73,7 @@ class System(SharedRegistryObject): #: Names of the _used_groups in used by this system. self._used_groups: set[str] = set() - self._computed_members: frozenset[str] | None = None + self._computed_members: Optional[frozenset[str]] = None # Add this system to the system dictionary self._REGISTRY._systems[self.name] = self @@ -154,7 +154,7 @@ class System(SharedRegistryObject): def from_definition( cls: type[System], system_definition: SystemDefinition, - get_root_func: GetRootUnits | None = None, + get_root_func: Optional[GetRootUnits] = None, ) -> System: if get_root_func is None: # TODO: kept for backwards compatibility diff --git a/pint/facets/system/registry.py b/pint/facets/system/registry.py index 30921bd..04aaea7 100644 --- a/pint/facets/system/registry.py +++ b/pint/facets/system/registry.py @@ -9,7 +9,7 @@ from __future__ import annotations from numbers import Number -from typing import TYPE_CHECKING, Generic, Any +from typing import TYPE_CHECKING, Generic, Any, Union, Optional from ... import errors @@ -53,17 +53,16 @@ class GenericSystemRegistry( # to enjoy typing goodies System: type[objects.System] - def __init__(self, system: str | None = None, **kwargs): + def __init__(self, system: Optional[str] = None, **kwargs): super().__init__(**kwargs) #: Map system name to system. - #: :type: dict[ str | System] self._systems: dict[str, objects.System] = {} #: Maps dimensionality (UnitsContainer) to Dimensionality (UnitsContainer) self._base_units_cache: dict[UnitsContainerT, UnitsContainerT] = {} - self._default_system_name: str | None = system + self._default_system_name: Optional[str] = system def _init_dynamic_classes(self) -> None: """Generate subclasses on the fly and attach them to self""" @@ -104,7 +103,7 @@ class GenericSystemRegistry( return objects.Lister(self._systems) @property - def default_system(self) -> str | None: + def default_system(self) -> Optional[str]: return self._default_system_name @default_system.setter @@ -144,9 +143,9 @@ class GenericSystemRegistry( def get_base_units( self, - input_units: UnitLike | Quantity, + input_units: Union[UnitLike, Quantity], check_nonmult: bool = True, - system: str | objects.System | None = None, + system: Optional[Union[str, objects.System]] = None, ) -> tuple[Number, Unit]: """Convert unit or dict of units to the plain units. @@ -184,7 +183,7 @@ class GenericSystemRegistry( self, input_units: UnitsContainerT, check_nonmult: bool = True, - system: str | objects.System | None = None, + system: Optional[Union[str, objects.System]] = None, ): if system is None: system = self._default_system_name @@ -226,7 +225,7 @@ class GenericSystemRegistry( return base_factor, destination_units def get_compatible_units( - self, input_units: UnitsContainerT, group_or_system: str | None = None + self, input_units: UnitsContainerT, group_or_system: Optional[str] = None ) -> frozenset[Unit]: """ """ @@ -242,7 +241,7 @@ class GenericSystemRegistry( return frozenset(self.Unit(eq) for eq in equiv) def _get_compatible_units( - self, input_units: UnitsContainerT, group_or_system: str | None = None + self, input_units: UnitsContainerT, group_or_system: Optional[str] = None ) -> frozenset[Unit]: if group_or_system and group_or_system in self._systems: members = self._systems[group_or_system].members diff --git a/pint/formatting.py b/pint/formatting.py index 1002aa6..561133c 100644 --- a/pint/formatting.py +++ b/pint/formatting.py @@ -13,7 +13,7 @@ from __future__ import annotations import functools import re import warnings -from typing import Callable, Any, TYPE_CHECKING, TypeVar +from typing import Callable, Any, TYPE_CHECKING, TypeVar, Optional, Union from collections.abc import Iterable from numbers import Number @@ -300,7 +300,7 @@ def formatter( power_fmt: str = "{} ** {}", parentheses_fmt: str = "({0})", exp_call: FORMATTER = "{:n}".format, - locale: str | None = None, + locale: Optional[str] = None, babel_length: str = "long", babel_plural_form: str = "one", sort: bool = True, @@ -455,7 +455,7 @@ def format_unit(unit, spec: str, registry=None, **options): def siunitx_format_unit(units: UnitsContainer, registry) -> str: """Returns LaTeX code for the unit that can be put into an siunitx command.""" - def _tothe(power: int | float) -> str: + def _tothe(power: Union[int, float]) -> str: if isinstance(power, int) or (isinstance(power, float) and power.is_integer()): if power == 1: return "" diff --git a/pint/pint_eval.py b/pint/pint_eval.py index d476eae..a2952ec 100644 --- a/pint/pint_eval.py +++ b/pint/pint_eval.py @@ -13,7 +13,7 @@ import operator import token as tokenlib from tokenize import TokenInfo -from typing import Any +from typing import Any, Optional, Union from .errors import DefinitionSyntaxError @@ -82,9 +82,9 @@ class EvalTreeNode: def __init__( self, - left: EvalTreeNode | TokenInfo, - operator: TokenInfo | None = None, - right: EvalTreeNode | None = None, + left: Union[EvalTreeNode, TokenInfo], + operator: Optional[TokenInfo] = None, + right: Optional[EvalTreeNode] = None, ): self.left = left self.operator = operator @@ -114,8 +114,8 @@ class EvalTreeNode: ], Any, ], - bin_op: dict[str, BinaryOpT] | None = None, - un_op: dict[str, UnaryOpT] | None = None, + bin_op: Optional[dict[str, BinaryOpT]] = None, + un_op: Optional[dict[str, UnaryOpT]] = None, ): """Evaluate node. @@ -291,7 +291,7 @@ def _build_eval_tree( def build_eval_tree( tokens: Iterable[TokenInfo], - op_priority: dict[str, int] | None = None, + op_priority: Optional[dict[str, int]] = None, ) -> EvalTreeNode: """Build an evaluation tree from a set of tokens. diff --git a/pint/registry_helpers.py b/pint/registry_helpers.py index 7eee694..6b2f0e0 100644 --- a/pint/registry_helpers.py +++ b/pint/registry_helpers.py @@ -13,7 +13,7 @@ from __future__ import annotations import functools from inspect import signature from itertools import zip_longest -from typing import TYPE_CHECKING, Callable, TypeVar, Any +from typing import TYPE_CHECKING, Callable, TypeVar, Any, Union, Optional from collections.abc import Iterable from ._typing import F @@ -186,8 +186,8 @@ def _apply_defaults(func, args, kwargs): def wraps( ureg: UnitRegistry, - ret: str | Unit | Iterable[str | Unit | None] | None, - args: str | Unit | Iterable[str | Unit | None] | None, + ret: Optional[Union[str, Unit, Iterable[Optional[Union[str, Unit]]]]], + args: Optional[Union[str, Unit, Iterable[Optional[Union[str, Unit]]]]], strict: bool = True, ) -> Callable[[Callable[..., Any]], Callable[..., Quantity]]: """Wraps a function to become pint-aware. @@ -301,7 +301,7 @@ def wraps( def check( - ureg: UnitRegistry, *args: str | UnitsContainer | Unit | None + ureg: UnitRegistry, *args: Optional[Union[str, UnitsContainer, Unit]] ) -> Callable[[F], F]: """Decorator to for quantity type checking for function inputs. diff --git a/pint/testing.py b/pint/testing.py index d99df0b..126a39f 100644 --- a/pint/testing.py +++ b/pint/testing.py @@ -3,6 +3,7 @@ from __future__ import annotations import math import warnings from numbers import Number +from typing import Optional from . import Quantity from .compat import ndarray @@ -34,7 +35,7 @@ def _get_comparable_magnitudes(first, second, msg): return m1, m2 -def assert_equal(first, second, msg: str | None = None) -> None: +def assert_equal(first, second, msg: Optional[str] = None) -> None: if msg is None: msg = f"Comparing {first!r} and {second!r}. " @@ -58,7 +59,7 @@ def assert_equal(first, second, msg: str | None = None) -> None: def assert_allclose( - first, second, rtol: float = 1e-07, atol: float = 0, msg: str | None = None + first, second, rtol: float = 1e-07, atol: float = 0, msg: Optional[str] = None ) -> None: if msg is None: try: diff --git a/pint/util.py b/pint/util.py index e250b0e..09aed5f 100644 --- a/pint/util.py +++ b/pint/util.py @@ -28,6 +28,7 @@ from typing import ( Callable, TypeVar, Any, + Optional, ) from collections.abc import Hashable, Generator @@ -63,8 +64,8 @@ def _noop(x: T) -> T: def matrix_to_string( matrix: ItMatrix, - row_headers: Iterable[str] | None = None, - col_headers: Iterable[str] | None = None, + row_headers: Optional[Iterable[str]] = None, + col_headers: Optional[Iterable[str]] = None, fmtfun: Callable[ [ Scalar, @@ -231,7 +232,7 @@ def column_echelon_form( return _transpose(ech_matrix), _transpose(id_matrix), swapped -def pi_theorem(quantities: dict[str, Any], registry: UnitRegistry | None = None): +def pi_theorem(quantities: dict[str, Any], registry: Optional[UnitRegistry] = None): """Builds dimensionless quantities using the Buckingham π theorem Parameters @@ -347,7 +348,7 @@ def solve_dependencies( def find_shortest_path( - graph: dict[TH, set[TH]], start: TH, end: TH, path: list[TH] | None = None + graph: dict[TH, set[TH]], start: TH, end: TH, path: Optional[list[TH]] = None ): """Find shortest path between two nodes within a graph. @@ -389,8 +390,8 @@ def find_shortest_path( def find_connected_nodes( - graph: dict[TH, set[TH]], start: TH, visited: set[TH] | None = None -) -> set[TH] | None: + graph: dict[TH, set[TH]], start: TH, visited: Optional[set[TH]] = None +) -> Optional[set[TH]]: """Find all nodes connected to a start node within a graph. Parameters @@ -449,12 +450,12 @@ class UnitsContainer(Mapping[str, Scalar]): __slots__ = ("_d", "_hash", "_one", "_non_int_type") _d: udict - _hash: int | None + _hash: Optional[int] _one: Scalar _non_int_type: type def __init__( - self, *args: Any, non_int_type: type | None = None, **kwargs: Any + self, *args: Any, non_int_type: Optional[type] = None, **kwargs: Any ) -> None: if args and isinstance(args[0], UnitsContainer): default_non_int_type = args[0]._non_int_type @@ -1013,7 +1014,7 @@ class PrettyIPython: def to_units_container( - unit_like: QuantityOrUnitLike, registry: UnitRegistry | None = None + unit_like: QuantityOrUnitLike, registry: Optional[UnitRegistry] = None ) -> UnitsContainer: """Convert a unit compatible type to a UnitsContainer. @@ -1048,7 +1049,7 @@ def to_units_container( def infer_base_unit( - unit_like: QuantityOrUnitLike, registry: UnitRegistry | None = None + unit_like: QuantityOrUnitLike, registry: Optional[UnitRegistry] = None ) -> UnitsContainer: """ Given a Quantity or UnitLike, give the UnitsContainer for it's plain units. |