summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHernan Grecco <hgrecco@gmail.com>2023-04-30 13:30:07 -0300
committerHernan Grecco <hgrecco@gmail.com>2023-04-30 13:30:07 -0300
commitf536abcfbb823ba55a35922da94b26ecc5f6d7b8 (patch)
tree5be425e63950527c5b0c53cd73512c3975cd4943
parent5d3d6299c9cfef5b62366482590edd3c241d9944 (diff)
downloadpint-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__.py4
-rw-r--r--pint/facets/context/registry.py20
-rw-r--r--pint/facets/dask/__init__.py6
-rw-r--r--pint/facets/formatting/objects.py6
-rw-r--r--pint/facets/formatting/registry.py4
-rw-r--r--pint/facets/group/registry.py14
-rw-r--r--pint/facets/measurement/objects.py2
-rw-r--r--pint/facets/measurement/registry.py16
-rw-r--r--pint/facets/nonmultiplicative/objects.py4
-rw-r--r--pint/facets/nonmultiplicative/registry.py2
-rw-r--r--pint/facets/numpy/quantity.py4
-rw-r--r--pint/facets/numpy/registry.py4
-rw-r--r--pint/facets/numpy/unit.py3
-rw-r--r--pint/facets/plain/registry.py12
-rw-r--r--pint/facets/system/registry.py8
-rw-r--r--pint/registry.py32
-rw-r--r--pint/util.py28
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.