From 11fead308ce398d8b1a1641cc1ba8450fbb93c41 Mon Sep 17 00:00:00 2001 From: Keewis Date: Thu, 5 Aug 2021 19:23:36 +0200 Subject: add a draft of the registry wrapper class --- pint/registry.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pint/registry.py b/pint/registry.py index 4428ad4..ff4df84 100644 --- a/pint/registry.py +++ b/pint/registry.py @@ -2323,3 +2323,17 @@ class LazyRegistry: def __call__(self, *args, **kwargs): self.__init() return self(*args, **kwargs) + + +class ApplicationRegistry: + def __init__(self, registry): + self._registry = registry + + def set(self, new_registry): + self._registry = new_registry + + def __getattr__(self, name): + return getattr(self._registry, name) + + def __dir__(self): + return dir(self._registry) -- cgit v1.2.1 From 0b5d917caf90657d05f1dd38a5af817fbf00a82d Mon Sep 17 00:00:00 2001 From: Keewis Date: Thu, 5 Aug 2021 19:24:39 +0200 Subject: manually override a few dunder methods --- pint/registry.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pint/registry.py b/pint/registry.py index ff4df84..d94bb4f 100644 --- a/pint/registry.py +++ b/pint/registry.py @@ -2337,3 +2337,15 @@ class ApplicationRegistry: def __dir__(self): return dir(self._registry) + + def __getitem__(self, item): + return self._registry[item] + + def __call__(self, *args, **kwargs): + return self._registry(*args, **kwargs) + + def __contains__(self, item): + return self._registry.__contains__(item) + + def __iter__(self): + return iter(self._registry) -- cgit v1.2.1 From 619c8e5f8cf7f4b2a3f9b2bf7c890b98a14ccb81 Mon Sep 17 00:00:00 2001 From: Keewis Date: Thu, 5 Aug 2021 19:26:29 +0200 Subject: add the application registry object --- pint/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pint/__init__.py b/pint/__init__.py index 3db4bb5..5788d1c 100644 --- a/pint/__init__.py +++ b/pint/__init__.py @@ -25,7 +25,7 @@ from .errors import ( # noqa: F401 from .formatting import formatter from .measurement import Measurement from .quantity import Quantity -from .registry import LazyRegistry, UnitRegistry +from .registry import ApplicationRegistry, LazyRegistry, UnitRegistry from .unit import Unit from .util import logger, pi_theorem @@ -48,6 +48,7 @@ _DEFAULT_REGISTRY = LazyRegistry() #: Registry used for unpickling operations. _APP_REGISTRY = _DEFAULT_REGISTRY +application_registry = ApplicationRegistry(_DEFAULT_REGISTRY) def _unpickle(cls, *args): -- cgit v1.2.1 From 08abfd0ede1d720f501730bd8d09c0a7b88e5135 Mon Sep 17 00:00:00 2001 From: Keewis Date: Thu, 5 Aug 2021 19:35:14 +0200 Subject: reimplement `get_application_registry` and `set_application_registry` --- pint/__init__.py | 10 +++------- pint/registry.py | 5 +++++ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/pint/__init__.py b/pint/__init__.py index 5788d1c..0f7d2f2 100644 --- a/pint/__init__.py +++ b/pint/__init__.py @@ -27,7 +27,7 @@ from .measurement import Measurement from .quantity import Quantity from .registry import ApplicationRegistry, LazyRegistry, UnitRegistry from .unit import Unit -from .util import logger, pi_theorem +from .util import logger, pi_theorem # noqa: F401 try: from importlib.metadata import version @@ -101,11 +101,7 @@ def set_application_registry(registry): ---------- registry : pint.UnitRegistry """ - if not isinstance(registry, (LazyRegistry, UnitRegistry)): - raise TypeError("Expected UnitRegistry; got %s" % type(registry)) - global _APP_REGISTRY - logger.debug("Changing app registry from %r to %r.", _APP_REGISTRY, registry) - _APP_REGISTRY = registry + application_registry.set(registry) def get_application_registry(): @@ -117,7 +113,7 @@ def get_application_registry(): ------- pint.UnitRegistry """ - return _APP_REGISTRY + return application_registry def test(): diff --git a/pint/registry.py b/pint/registry.py index d94bb4f..3d3ee91 100644 --- a/pint/registry.py +++ b/pint/registry.py @@ -2330,6 +2330,11 @@ class ApplicationRegistry: self._registry = registry def set(self, new_registry): + if not isinstance(new_registry, (LazyRegistry, UnitRegistry)): + raise TypeError("Expected UnitRegistry; got %s" % type(new_registry)) + logger.debug( + "Changing app registry from %r to %r.", self._registry, new_registry + ) self._registry = new_registry def __getattr__(self, name): -- cgit v1.2.1 From 735eb3a016b9d128ed75594b4e7ee1a52f8419d2 Mon Sep 17 00:00:00 2001 From: Keewis Date: Thu, 5 Aug 2021 19:49:27 +0200 Subject: assign _APP_REGISTRY to the new name --- pint/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pint/__init__.py b/pint/__init__.py index 0f7d2f2..d652f5a 100644 --- a/pint/__init__.py +++ b/pint/__init__.py @@ -47,8 +47,8 @@ except Exception: # pragma: no cover _DEFAULT_REGISTRY = LazyRegistry() #: Registry used for unpickling operations. -_APP_REGISTRY = _DEFAULT_REGISTRY application_registry = ApplicationRegistry(_DEFAULT_REGISTRY) +_APP_REGISTRY = application_registry def _unpickle(cls, *args): -- cgit v1.2.1 From 816ee0974d2f688c8e3048beb777446b12825275 Mon Sep 17 00:00:00 2001 From: Keewis Date: Thu, 5 Aug 2021 19:50:13 +0200 Subject: allow setting the object returned by `get_application_registry` --- pint/registry.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pint/registry.py b/pint/registry.py index 3d3ee91..d848feb 100644 --- a/pint/registry.py +++ b/pint/registry.py @@ -2330,6 +2330,9 @@ class ApplicationRegistry: self._registry = registry def set(self, new_registry): + if isinstance(new_registry, type(self)): + new_registry = new_registry._registry + if not isinstance(new_registry, (LazyRegistry, UnitRegistry)): raise TypeError("Expected UnitRegistry; got %s" % type(new_registry)) logger.debug( -- cgit v1.2.1 From 9de66105bf871f5f5f976eea837d48bca238873e Mon Sep 17 00:00:00 2001 From: Keewis Date: Thu, 5 Aug 2021 19:51:02 +0200 Subject: don't type check the value returned by `get_application_registry()` --- pint/testsuite/test_application_registry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pint/testsuite/test_application_registry.py b/pint/testsuite/test_application_registry.py index 59c3521..97ce3fb 100644 --- a/pint/testsuite/test_application_registry.py +++ b/pint/testsuite/test_application_registry.py @@ -102,7 +102,7 @@ class TestCustomApplicationRegistry: cls.ureg.define("foo = []") cls.ureg.define("bar = foo / 2") set_application_registry(cls.ureg) - assert get_application_registry() is cls.ureg + # assert get_application_registry() is cls.ureg @classmethod def teardown_class(cls): -- cgit v1.2.1 From 2e011924e3ac8815cced2556615e83982402ef2f Mon Sep 17 00:00:00 2001 From: Keewis Date: Fri, 6 Aug 2021 00:05:54 +0200 Subject: save the actual registry in shared registry objects --- pint/registry.py | 3 +++ pint/util.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/pint/registry.py b/pint/registry.py index d848feb..892a075 100644 --- a/pint/registry.py +++ b/pint/registry.py @@ -2329,6 +2329,9 @@ class ApplicationRegistry: def __init__(self, registry): self._registry = registry + def get(self): + return self._registry + def set(self, new_registry): if isinstance(new_registry, type(self)): new_registry = new_registry._registry diff --git a/pint/util.py b/pint/util.py index 18474ec..a2f34d6 100644 --- a/pint/util.py +++ b/pint/util.py @@ -820,7 +820,7 @@ class SharedRegistryObject: # UnitRegistry._init_dynamic_classes from . import _APP_REGISTRY - inst._REGISTRY = _APP_REGISTRY + inst._REGISTRY = _APP_REGISTRY.get() return inst def _check(self, other) -> bool: -- cgit v1.2.1 From 5fea75380d434b7f5e407aa2d8420db78332066c Mon Sep 17 00:00:00 2001 From: Keewis Date: Sun, 8 Aug 2021 01:28:12 +0200 Subject: remove _APP_DIR --- pint/__init__.py | 9 ++++----- pint/util.py | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/pint/__init__.py b/pint/__init__.py index d652f5a..9f126d5 100644 --- a/pint/__init__.py +++ b/pint/__init__.py @@ -48,7 +48,6 @@ _DEFAULT_REGISTRY = LazyRegistry() #: Registry used for unpickling operations. application_registry = ApplicationRegistry(_DEFAULT_REGISTRY) -_APP_REGISTRY = application_registry def _unpickle(cls, *args): @@ -73,24 +72,24 @@ def _unpickle(cls, *args): # We need to make sure that this happens before using. if isinstance(arg, UnitsContainer): for name in arg: - _APP_REGISTRY.parse_units(name) + application_registry.parse_units(name) return cls(*args) def _unpickle_quantity(cls, *args): """Rebuild quantity upon unpickling using the application registry.""" - return _unpickle(_APP_REGISTRY.Quantity, *args) + return _unpickle(application_registry.Quantity, *args) def _unpickle_unit(cls, *args): """Rebuild unit upon unpickling using the application registry.""" - return _unpickle(_APP_REGISTRY.Unit, *args) + return _unpickle(application_registry.Unit, *args) def _unpickle_measurement(cls, *args): """Rebuild measurement upon unpickling using the application registry.""" - return _unpickle(_APP_REGISTRY.Measurement, *args) + return _unpickle(application_registry.Measurement, *args) def set_application_registry(registry): diff --git a/pint/util.py b/pint/util.py index a2f34d6..46105f4 100644 --- a/pint/util.py +++ b/pint/util.py @@ -818,9 +818,9 @@ class SharedRegistryObject: if not hasattr(cls, "_REGISTRY"): # Base class, not subclasses dynamically by # UnitRegistry._init_dynamic_classes - from . import _APP_REGISTRY + from . import application_registry - inst._REGISTRY = _APP_REGISTRY.get() + inst._REGISTRY = application_registry.get() return inst def _check(self, other) -> bool: -- cgit v1.2.1 From 7e53f25d74b1113c3b0c55ad506edf5f75c40cdc Mon Sep 17 00:00:00 2001 From: Keewis Date: Sun, 8 Aug 2021 01:44:33 +0200 Subject: use the public method --- pint/registry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pint/registry.py b/pint/registry.py index 892a075..c6bdcdc 100644 --- a/pint/registry.py +++ b/pint/registry.py @@ -2334,7 +2334,7 @@ class ApplicationRegistry: def set(self, new_registry): if isinstance(new_registry, type(self)): - new_registry = new_registry._registry + new_registry = new_registry.get() if not isinstance(new_registry, (LazyRegistry, UnitRegistry)): raise TypeError("Expected UnitRegistry; got %s" % type(new_registry)) -- cgit v1.2.1 From 6d1f192572b4f0c1f8cef66335ef3b9f367193f9 Mon Sep 17 00:00:00 2001 From: Keewis Date: Sun, 8 Aug 2021 01:46:53 +0200 Subject: properly isolate the application registry using fixtures --- pint/testsuite/test_application_registry.py | 51 ++++++++++++++--------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/pint/testsuite/test_application_registry.py b/pint/testsuite/test_application_registry.py index 97ce3fb..fbd8026 100644 --- a/pint/testsuite/test_application_registry.py +++ b/pint/testsuite/test_application_registry.py @@ -5,6 +5,7 @@ import pickle import pytest from pint import ( + ApplicationRegistry, Measurement, Quantity, UndefinedUnitError, @@ -16,6 +17,14 @@ from pint import ( from pint.testsuite import helpers +@pytest.fixture +def isolate_application_registry(monkeypatch): + import pint + + new = ApplicationRegistry(UnitRegistry()) + monkeypatch.setattr(pint, "application_registry", new) + + class TestDefaultApplicationRegistry: @helpers.allprotos def test_unit(self, protocol): @@ -94,20 +103,16 @@ class TestDefaultApplicationRegistry: pickle.loads(b) -class TestCustomApplicationRegistry: - @classmethod - def setup_class(cls): - cls.ureg_bak = get_application_registry() - cls.ureg = UnitRegistry(None) - cls.ureg.define("foo = []") - cls.ureg.define("bar = foo / 2") - set_application_registry(cls.ureg) - # assert get_application_registry() is cls.ureg - - @classmethod - def teardown_class(cls): - set_application_registry(cls.ureg_bak) +@pytest.fixture +def custom_registry(isolate_application_registry): + ureg = UnitRegistry(None) + ureg.define("foo = []") + ureg.define("bar = foo / 2") + set_application_registry(ureg) + +@pytest.mark.usefixtures("custom_registry") +class TestCustomApplicationRegistry: @helpers.allprotos def test_unit(self, protocol): u = Unit("foo") @@ -158,6 +163,7 @@ class TestCustomApplicationRegistry: assert str(m.units) == "foo" +@pytest.mark.usefixtures("isolate_application_registry") class TestSwapApplicationRegistry: """Test that the constructors of Quantity, Unit, and Measurement capture the registry that is set as the application registry at creation time @@ -170,19 +176,12 @@ class TestSwapApplicationRegistry: """ - @classmethod - def setup_class(cls): - cls.ureg_bak = get_application_registry() - cls.ureg1 = UnitRegistry(None) - cls.ureg1.define("foo = [dim1]") - cls.ureg1.define("bar = foo / 2") - cls.ureg2 = UnitRegistry(None) - cls.ureg2.define("foo = [dim2]") - cls.ureg2.define("bar = foo / 3") - - @classmethod - def teardown_class(cls): - set_application_registry(cls.ureg_bak) + ureg1 = UnitRegistry(None) + ureg1.define("foo = [dim1]") + ureg1.define("bar = foo / 2") + ureg2 = UnitRegistry(None) + ureg2.define("foo = [dim2]") + ureg2.define("bar = foo / 3") @helpers.allprotos def test_quantity_1arg(self, protocol): -- cgit v1.2.1 From 7b8bc3e13482102f50d27dcd68bca39f296ac361 Mon Sep 17 00:00:00 2001 From: Keewis Date: Sun, 8 Aug 2021 11:09:04 +0200 Subject: add a test checking that saved registries are properly updated --- pint/testsuite/test_application_registry.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pint/testsuite/test_application_registry.py b/pint/testsuite/test_application_registry.py index fbd8026..2ec349c 100644 --- a/pint/testsuite/test_application_registry.py +++ b/pint/testsuite/test_application_registry.py @@ -258,3 +258,15 @@ class TestSwapApplicationRegistry: assert m1.to("bar").error.magnitude == 2 assert m2.to("bar").error.magnitude == 3 assert m3.to("bar").error.magnitude == 3 + + +@pytest.mark.usefixtures("isolate_application_registry") +def test_update_saved_registries(): + ureg1 = get_application_registry() + ureg2 = get_application_registry() + + new = UnitRegistry() + new.define("foo = []") + set_application_registry(new) + + assert ureg1.Unit("foo") == ureg2.Unit("foo") -- cgit v1.2.1 From c135b5c995f058ade8c98298cbe7061b4e50675a Mon Sep 17 00:00:00 2001 From: Keewis Date: Sat, 14 Aug 2021 14:50:33 +0200 Subject: add docstrings to the application registry --- pint/registry.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pint/registry.py b/pint/registry.py index c6bdcdc..f53becc 100644 --- a/pint/registry.py +++ b/pint/registry.py @@ -2326,13 +2326,27 @@ class LazyRegistry: class ApplicationRegistry: + """A wrapper class used to distribute changes to the application registry.""" + def __init__(self, registry): self._registry = registry def get(self): + """Get the wrapped registry""" return self._registry def set(self, new_registry): + """Set the new registry + + Parameters + ---------- + new_registry : ApplicationRegistry or LazyRegistry or UnitRegistry + The new registry. + + See Also + -------- + set_application_registry + """ if isinstance(new_registry, type(self)): new_registry = new_registry.get() -- cgit v1.2.1 From 1a8e7e7d8e0ceb77d06e93dd1d9e8828bfa84921 Mon Sep 17 00:00:00 2001 From: Keewis Date: Fri, 20 Aug 2021 11:48:45 +0200 Subject: update CHANGES --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index 477aa09..e53cc5b 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,7 @@ Pint Changelog - Fix string formatting of numpy array scalars - Fix default format for Measurement class (Issue #1300) - Fix parsing of pretty units with same exponents but different sign. (Issue #1360) +- Convert the application registry to a wrapper object (Issue #1365) ### Breaking Changes -- cgit v1.2.1