diff options
author | Hernan Grecco <hgrecco@gmail.com> | 2023-04-30 13:30:07 -0300 |
---|---|---|
committer | Hernan Grecco <hgrecco@gmail.com> | 2023-04-30 13:30:07 -0300 |
commit | f536abcfbb823ba55a35922da94b26ecc5f6d7b8 (patch) | |
tree | 5be425e63950527c5b0c53cd73512c3975cd4943 | |
parent | 5d3d6299c9cfef5b62366482590edd3c241d9944 (diff) | |
download | pint-f536abcfbb823ba55a35922da94b26ecc5f6d7b8.tar.gz |
Reworked the Quantity, Unit, Measurement, Group and System class to be static to ease with typing
-rw-r--r-- | pint/facets/__init__.py | 4 | ||||
-rw-r--r-- | pint/facets/context/registry.py | 20 | ||||
-rw-r--r-- | pint/facets/dask/__init__.py | 6 | ||||
-rw-r--r-- | pint/facets/formatting/objects.py | 6 | ||||
-rw-r--r-- | pint/facets/formatting/registry.py | 4 | ||||
-rw-r--r-- | pint/facets/group/registry.py | 14 | ||||
-rw-r--r-- | pint/facets/measurement/objects.py | 2 | ||||
-rw-r--r-- | pint/facets/measurement/registry.py | 16 | ||||
-rw-r--r-- | pint/facets/nonmultiplicative/objects.py | 4 | ||||
-rw-r--r-- | pint/facets/nonmultiplicative/registry.py | 2 | ||||
-rw-r--r-- | pint/facets/numpy/quantity.py | 4 | ||||
-rw-r--r-- | pint/facets/numpy/registry.py | 4 | ||||
-rw-r--r-- | pint/facets/numpy/unit.py | 3 | ||||
-rw-r--r-- | pint/facets/plain/registry.py | 12 | ||||
-rw-r--r-- | pint/facets/system/registry.py | 8 | ||||
-rw-r--r-- | pint/registry.py | 32 | ||||
-rw-r--r-- | pint/util.py | 28 |
17 files changed, 80 insertions, 89 deletions
diff --git a/pint/facets/__init__.py b/pint/facets/__init__.py index d669b9f..7b24463 100644 --- a/pint/facets/__init__.py +++ b/pint/facets/__init__.py @@ -30,8 +30,8 @@ class NumpyRegistry: - _quantity_class = NumpyQuantity - _unit_class = NumpyUnit + Quantity = NumpyQuantity + Unit = NumpyUnit This tells pint that it should use NumpyQuantity as base class for a quantity class that belongs to a registry that has NumpyRegistry as one of its bases. diff --git a/pint/facets/context/registry.py b/pint/facets/context/registry.py index 108bdf0..a36d82d 100644 --- a/pint/facets/context/registry.py +++ b/pint/facets/context/registry.py @@ -18,7 +18,7 @@ from ...errors import UndefinedUnitError from ...util import find_connected_nodes, find_shortest_path, logger from ..plain import PlainRegistry, UnitDefinition from .definitions import ContextDefinition -from .objects import Context, ContextChain +from . import objects # TODO: Put back annotation when possible # registry_cache: "RegistryCache" @@ -50,13 +50,13 @@ class ContextRegistry(PlainRegistry): - Parse @context directive. """ - Context = Context + Context = objects.Context def __init__(self, **kwargs: Any) -> None: # Map context name (string) or abbreviation to context. - self._contexts: dict[str, Context] = {} + self._contexts: dict[str, objects.Context] = {} # Stores active contexts. - self._active_ctx = ContextChain() + self._active_ctx = objects.ContextChain() # Map context chain to cache self._caches = {} # Map context chain to units override @@ -80,7 +80,7 @@ class ContextRegistry(PlainRegistry): see :meth:`enable_contexts`. """ if isinstance(context, ContextDefinition): - context = Context.from_definition(context, self.get_dimensionality) + context = objects.Context.from_definition(context, self.get_dimensionality) if not context.name: raise ValueError("Can't add unnamed context to registry") @@ -97,7 +97,7 @@ class ContextRegistry(PlainRegistry): ) self._contexts[alias] = context - def remove_context(self, name_or_alias: str) -> Context: + def remove_context(self, name_or_alias: str) -> objects.Context: """Remove a context from the registry and return it. Notice that this methods will not disable the context; @@ -193,7 +193,9 @@ class ContextRegistry(PlainRegistry): # Write into the context-specific self._units.maps[0] and self._cache.root_units self.define(definition) - def enable_contexts(self, *names_or_contexts: str | Context, **kwargs) -> None: + def enable_contexts( + self, *names_or_contexts: str | objects.Context, **kwargs + ) -> None: """Enable contexts provided by name or by object. Parameters @@ -233,7 +235,7 @@ class ContextRegistry(PlainRegistry): ctx.checked = True # and create a new one with the new defaults. - contexts = tuple(Context.from_context(ctx, **kwargs) for ctx in ctxs) + contexts = tuple(objects.Context.from_context(ctx, **kwargs) for ctx in ctxs) # Finally we add them to the active context. self._active_ctx.insert_contexts(*contexts) @@ -251,7 +253,7 @@ class ContextRegistry(PlainRegistry): self._switch_context_cache_and_units() @contextmanager - def context(self, *names, **kwargs) -> ContextManager[Context]: + def context(self, *names, **kwargs) -> ContextManager[objects.Context]: """Used as a context manager, this function enables to activate a context which is removed after usage. diff --git a/pint/facets/dask/__init__.py b/pint/facets/dask/__init__.py index e0821be..90c8972 100644 --- a/pint/facets/dask/__init__.py +++ b/pint/facets/dask/__init__.py @@ -14,7 +14,7 @@ from __future__ import annotations import functools from ...compat import compute, dask_array, persist, visualize -from ..plain import PlainRegistry +from ..plain import PlainRegistry, PlainQuantity def check_dask_array(f): @@ -31,7 +31,7 @@ def check_dask_array(f): return wrapper -class DaskQuantity: +class DaskQuantity(PlainQuantity): # Dask.array.Array ducking def __dask_graph__(self): if isinstance(self._magnitude, dask_array.Array): @@ -120,4 +120,4 @@ class DaskQuantity: class DaskRegistry(PlainRegistry): - _quantity_class = DaskQuantity + Quantity = DaskQuantity diff --git a/pint/facets/formatting/objects.py b/pint/facets/formatting/objects.py index fa5ca83..5df937c 100644 --- a/pint/facets/formatting/objects.py +++ b/pint/facets/formatting/objects.py @@ -23,8 +23,10 @@ from ...formatting import ( ) from ...util import UnitsContainer, iterable +from ..plain import PlainQuantity, PlainUnit -class FormattingQuantity: + +class FormattingQuantity(PlainQuantity): _exp_pattern = re.compile(r"([0-9]\.?[0-9]*)e(-?)\+?0*([0-9]+)") def __format__(self, spec: str) -> str: @@ -176,7 +178,7 @@ class FormattingQuantity: return format(self) -class FormattingUnit: +class FormattingUnit(PlainUnit): def __str__(self): return format(self) diff --git a/pint/facets/formatting/registry.py b/pint/facets/formatting/registry.py index bd9c74c..c4dc373 100644 --- a/pint/facets/formatting/registry.py +++ b/pint/facets/formatting/registry.py @@ -13,5 +13,5 @@ from .objects import FormattingQuantity, FormattingUnit class FormattingRegistry(PlainRegistry): - _quantity_class = FormattingQuantity - _unit_class = FormattingUnit + Quantity = FormattingQuantity + Unit = FormattingUnit diff --git a/pint/facets/group/registry.py b/pint/facets/group/registry.py index c6cc06d..0d35ae0 100644 --- a/pint/facets/group/registry.py +++ b/pint/facets/group/registry.py @@ -15,10 +15,10 @@ from ... import errors if TYPE_CHECKING: from ..._typing import Unit -from ...util import build_dependent_class, create_class_with_registry +from ...util import create_class_with_registry from ..plain import PlainRegistry, UnitDefinition from .definitions import GroupDefinition -from .objects import Group +from . import objects class GroupRegistry(PlainRegistry): @@ -34,19 +34,15 @@ class GroupRegistry(PlainRegistry): # TODO: Change this to Group: Group to specify class # and use introspection to get system class as a way # to enjoy typing goodies - _group_class = Group + Group = objects.Group def __init__(self, **kwargs): super().__init__(**kwargs) #: Map group name to group. #: :type: dict[ str | Group] - self._groups: dict[str, Group] = {} + self._groups: dict[str, objects.Group] = {} self._groups["root"] = self.Group("root") - def __init_subclass__(cls, **kwargs): - super().__init_subclass__() - cls.Group = build_dependent_class(cls, "Group", "_group_class") - def _init_dynamic_classes(self) -> None: """Generate subclasses on the fly and attach them to self""" super()._init_dynamic_classes() @@ -93,7 +89,7 @@ class GroupRegistry(PlainRegistry): except KeyError as e: raise errors.DefinitionSyntaxError(f"unknown dimension {e} in context") - def get_group(self, name: str, create_if_needed: bool = True) -> Group: + def get_group(self, name: str, create_if_needed: bool = True) -> objects.Group: """Return a Group. Parameters diff --git a/pint/facets/measurement/objects.py b/pint/facets/measurement/objects.py index aaf5750..5f3ba7a 100644 --- a/pint/facets/measurement/objects.py +++ b/pint/facets/measurement/objects.py @@ -18,7 +18,7 @@ from ..plain import PlainQuantity MISSING = object() -class MeasurementQuantity: +class MeasurementQuantity(PlainQuantity): # Measurement support def plus_minus(self, error, relative=False): if isinstance(error, self.__class__): diff --git a/pint/facets/measurement/registry.py b/pint/facets/measurement/registry.py index e704399..0fc4391 100644 --- a/pint/facets/measurement/registry.py +++ b/pint/facets/measurement/registry.py @@ -10,21 +10,15 @@ from __future__ import annotations from ...compat import ufloat -from ...util import build_dependent_class, create_class_with_registry +from ...util import create_class_with_registry from ..plain import PlainRegistry -from .objects import Measurement, MeasurementQuantity +from .objects import MeasurementQuantity +from . import objects class MeasurementRegistry(PlainRegistry): - _quantity_class = MeasurementQuantity - _measurement_class = Measurement - - def __init_subclass__(cls, **kwargs): - super().__init_subclass__() - - cls.Measurement = build_dependent_class( - cls, "Measurement", "_measurement_class" - ) + Quantity = MeasurementQuantity + Measurement = objects.Measurement def _init_dynamic_classes(self) -> None: """Generate subclasses on the fly and attach them to self""" diff --git a/pint/facets/nonmultiplicative/objects.py b/pint/facets/nonmultiplicative/objects.py index a0456de..7f9064d 100644 --- a/pint/facets/nonmultiplicative/objects.py +++ b/pint/facets/nonmultiplicative/objects.py @@ -8,8 +8,10 @@ from __future__ import annotations +from ..plain import PlainQuantity -class NonMultiplicativeQuantity: + +class NonMultiplicativeQuantity(PlainQuantity): @property def _is_multiplicative(self) -> bool: """Check if the PlainQuantity object has only multiplicative units.""" diff --git a/pint/facets/nonmultiplicative/registry.py b/pint/facets/nonmultiplicative/registry.py index 9bbc1aa..8bc04db 100644 --- a/pint/facets/nonmultiplicative/registry.py +++ b/pint/facets/nonmultiplicative/registry.py @@ -35,7 +35,7 @@ class NonMultiplicativeRegistry(PlainRegistry): """ - _quantity_class = NonMultiplicativeQuantity + Quantity = NonMultiplicativeQuantity def __init__( self, diff --git a/pint/facets/numpy/quantity.py b/pint/facets/numpy/quantity.py index 410654a..131983c 100644 --- a/pint/facets/numpy/quantity.py +++ b/pint/facets/numpy/quantity.py @@ -13,6 +13,8 @@ import math import warnings from typing import Any +from ..plain import PlainQuantity + from ..._typing import Shape, _MagnitudeType from ...compat import _to_magnitude, np from ...errors import DimensionalityError, PintTypeError, UnitStrippedWarning @@ -40,7 +42,7 @@ def method_wraps(numpy_func): return wrapper -class NumpyQuantity: +class NumpyQuantity(PlainQuantity): """ """ # NumPy function/ufunc support diff --git a/pint/facets/numpy/registry.py b/pint/facets/numpy/registry.py index fa4768f..11d57f3 100644 --- a/pint/facets/numpy/registry.py +++ b/pint/facets/numpy/registry.py @@ -15,5 +15,5 @@ from .unit import NumpyUnit class NumpyRegistry(PlainRegistry): - _quantity_class = NumpyQuantity - _unit_class = NumpyUnit + Quantity = NumpyQuantity + Unit = NumpyUnit diff --git a/pint/facets/numpy/unit.py b/pint/facets/numpy/unit.py index 21b3594..d6bf140 100644 --- a/pint/facets/numpy/unit.py +++ b/pint/facets/numpy/unit.py @@ -9,9 +9,10 @@ from __future__ import annotations from ...compat import is_upcast_type +from ..plain import PlainUnit -class NumpyUnit: +class NumpyUnit(PlainUnit): __array_priority__ = 17 def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): diff --git a/pint/facets/plain/registry.py b/pint/facets/plain/registry.py index a35e508..d3baff4 100644 --- a/pint/facets/plain/registry.py +++ b/pint/facets/plain/registry.py @@ -43,7 +43,6 @@ from ...util import UnitsContainer from ...util import UnitsContainer as UnitsContainerT from ...util import ( _is_dim, - build_dependent_class, create_class_with_registry, getattr_maybe_raise, logger, @@ -177,8 +176,8 @@ class PlainRegistry(metaclass=RegistryMeta): _diskcache = None - _quantity_class = PlainQuantity - _unit_class = PlainUnit + Quantity = PlainQuantity + Unit = PlainUnit _def_parser = None @@ -278,13 +277,6 @@ class PlainRegistry(metaclass=RegistryMeta): self._initialized = False - def __init_subclass__(cls, **kwargs): - super().__init_subclass__() - cls.Unit: Unit = build_dependent_class(cls, "Unit", "_unit_class") - cls.Quantity: Quantity = build_dependent_class( - cls, "Quantity", "_quantity_class" - ) - def _init_dynamic_classes(self) -> None: """Generate subclasses on the fly and attach them to self""" diff --git a/pint/facets/system/registry.py b/pint/facets/system/registry.py index accccb2..6e0878e 100644 --- a/pint/facets/system/registry.py +++ b/pint/facets/system/registry.py @@ -19,13 +19,13 @@ if TYPE_CHECKING: from ..._typing import UnitLike from ...util import UnitsContainer as UnitsContainerT from ...util import ( - build_dependent_class, create_class_with_registry, to_units_container, ) from ..group import GroupRegistry from .definitions import SystemDefinition from .objects import Lister, System +from . import objects class SystemRegistry(GroupRegistry): @@ -46,7 +46,7 @@ class SystemRegistry(GroupRegistry): # TODO: Change this to System: System to specify class # and use introspection to get system class as a way # to enjoy typing goodies - _system_class = System + System = objects.System def __init__(self, system=None, **kwargs): super().__init__(**kwargs) @@ -60,10 +60,6 @@ class SystemRegistry(GroupRegistry): self._default_system = system - def __init_subclass__(cls, **kwargs): - super().__init_subclass__() - cls.System = build_dependent_class(cls, "System", "_system_class") - def _init_dynamic_classes(self) -> None: """Generate subclasses on the fly and attach them to self""" super()._init_dynamic_classes() diff --git a/pint/registry.py b/pint/registry.py index 29d5c89..474eb77 100644 --- a/pint/registry.py +++ b/pint/registry.py @@ -27,6 +27,35 @@ from .facets import ( from .util import logger, pi_theorem +# To build the Quantity and Unit classes +# we follow the UnitRegistry bases +# but + + +class Quantity( + # SystemRegistry.Quantity, + # ContextRegistry.Quantity, + DaskRegistry.Quantity, + NumpyRegistry.Quantity, + MeasurementRegistry.Quantity, + FormattingRegistry.Quantity, + NonMultiplicativeRegistry.Quantity, +): + pass + + +class Unit( + # SystemRegistry.Unit, + # ContextRegistry.Unit, + # DaskRegistry.Unit, + NumpyRegistry.Unit, + # MeasurementRegistry.Unit, + FormattingRegistry.Unit, + NonMultiplicativeRegistry.Unit, +): + pass + + class UnitRegistry( SystemRegistry, ContextRegistry, @@ -72,6 +101,9 @@ class UnitRegistry( If None, the cache is disabled. (default) """ + Quantity = Quantity + Unit = Unit + def __init__( self, filename="", diff --git a/pint/util.py b/pint/util.py index a99d314..28710e7 100644 --- a/pint/util.py +++ b/pint/util.py @@ -10,8 +10,6 @@ from __future__ import annotations -import functools -import inspect import logging import math import operator @@ -1010,32 +1008,6 @@ def sized(y) -> bool: return True -@functools.cache -def _build_type(class_name: str, bases): - return type(class_name, bases, {}) - - -def build_dependent_class(registry_class, class_name: str, attribute_name: str) -> type: - """Creates a class specifically for the given registry that - subclass all the classes named by the registry bases in a - specific attribute - - 1. List the 'attribute_name' attribute for each of the bases of the registry class. - 2. Use this list as bases for the new class - 3. Add the provided registry as the class registry. - - """ - bases = ( - getattr(base, attribute_name) - for base in inspect.getmro(registry_class) - if attribute_name in base.__dict__ - ) - bases = tuple(dict.fromkeys(bases, None).keys()) - if len(bases) == 1 and bases[0].__name__ == class_name: - return bases[0] - return _build_type(class_name, bases) - - def create_class_with_registry(registry, base_class) -> type: """Create new class inheriting from base_class and filling _REGISTRY class attribute with an actual instanced registry. |