Repository: hgrecco/pint

Issue:
pickle Quantity
If I pickle a Quantity:
```python
import pint
import pickle
foo = pint.get_application_registry().Quantity(1, 's')
with open("file.pkl", 'bw') as f:
    pickle.dump(foo, f)
```
And the unpickle it (using the `application_registry` so it should work with pickle):
```python
import pint
import pickle
bar = pint.get_application_registry().Quantity(0.5, 's')
with open("file.pkl", 'br') as f:
    foo = pickle.load(f)

foo > bar
```
I get the following error.
```python
Traceback (most recent call last):

  File "C:\Users\Quentin.Peter\Desktop\untitled0.py", line 16, in <module>
    foo > bar

  File "C:\Users\Quentin.Peter\AppData\Local\Continuum\anaconda3\lib\site-packages\pint\quantity.py", line 1511, in <lambda>
    __lt__ = lambda self, other: self.compare(other, op=operator.lt)

  File "C:\Users\Quentin.Peter\AppData\Local\Continuum\anaconda3\lib\site-packages\pint\quantity.py", line 102, in wrapped
    result = f(self, *args, **kwargs)

  File "C:\Users\Quentin.Peter\AppData\Local\Continuum\anaconda3\lib\site-packages\pint\quantity.py", line 1501, in compare
    raise ValueError("Cannot compare Quantity and {}".format(type(other)))

ValueError: Cannot compare Quantity and <class 'pint.quantity.Quantity'>
```
I can fix it by adding in `__init__.py::_unpickle`
```python
if cls.__name__ == "Quantity":
        cls = _APP_REGISTRY.Quantity
```

Discussion:

Patch:
diff --git a/CHANGES b/CHANGES
index a3faeee..72853c2 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4,8 +4,8 @@ Pint Changelog
 0.17 (unreleased)
 --------------
 
-- Nothing changed yet.
-
+- Fix unpickling, now it is using the APP_REGISTRY as expected.
+  (Issue #1175)
 
 0.16 (2020-09-13)
 -----------------
diff --git a/pint/__init__.py b/pint/__init__.py
index 8bea195..2cd9c60 100644
--- a/pint/__init__.py
+++ b/pint/__init__.py
@@ -89,6 +89,24 @@ def _unpickle(cls, *args):
     return cls(*args)
 
 
+def _unpickle_quantity(cls, *args):
+    """Rebuild quantity upon unpickling using the application registry.
+    """
+    return _unpickle(_APP_REGISTRY.Quantity, *args)
+
+
+def _unpickle_unit(cls, *args):
+    """Rebuild unit upon unpickling using the application registry.
+    """
+    return _unpickle(_APP_REGISTRY.Unit, *args)
+
+
+def _unpickle_measurement(cls, *args):
+    """Rebuild measurement upon unpickling using the application registry.
+    """
+    return _unpickle(_APP_REGISTRY.Measurement, *args)
+
+
 def set_application_registry(registry):
     """Set the application registry, which is used for unpickling operations
     and when invoking pint.Quantity or pint.Unit directly.
diff --git a/pint/measurement.py b/pint/measurement.py
index 1da1b64..a1ca295 100644
--- a/pint/measurement.py
+++ b/pint/measurement.py
@@ -70,9 +70,9 @@ class Measurement(Quantity):
 
     def __reduce__(self):
         # See notes in Quantity.__reduce__
-        from . import _unpickle
+        from . import _unpickle_measurement
 
-        return _unpickle, (Measurement, self.magnitude, self._units)
+        return _unpickle_measurement, (Measurement, self.magnitude, self._units)
 
     def __repr__(self):
         return "<Measurement({}, {}, {})>".format(
diff --git a/pint/quantity.py b/pint/quantity.py
index 803b871..0395a65 100644
--- a/pint/quantity.py
+++ b/pint/quantity.py
@@ -192,11 +192,11 @@ class Quantity(PrettyIPython, SharedRegistryObject):
         """Allow pickling quantities. Since UnitRegistries are not pickled, upon
         unpickling the new object is always attached to the application registry.
         """
-        from . import _unpickle
+        from . import _unpickle_quantity
 
         # Note: type(self) would be a mistake as subclasses built by
         # build_quantity_class can't be pickled
-        return _unpickle, (Quantity, self.magnitude, self._units)
+        return _unpickle_quantity, (Quantity, self.magnitude, self._units)
 
     def __new__(cls, value, units=None):
         if is_upcast_type(type(value)):
diff --git a/pint/unit.py b/pint/unit.py
index f09f39e..eff3c4b 100644
--- a/pint/unit.py
+++ b/pint/unit.py
@@ -28,9 +28,9 @@ class Unit(PrettyIPython, SharedRegistryObject):
 
     def __reduce__(self):
         # See notes in Quantity.__reduce__
-        from . import _unpickle
+        from . import _unpickle_unit
 
-        return _unpickle, (Unit, self._units)
+        return _unpickle_unit, (Unit, self._units)
 
     def __init__(self, units):
         super().__init__()


Test patch:
diff --git a/pint/testsuite/test_issues.py b/pint/testsuite/test_issues.py
index a1ca050..e39b01a 100644
--- a/pint/testsuite/test_issues.py
+++ b/pint/testsuite/test_issues.py
@@ -5,7 +5,7 @@ import unittest
 
 import pytest
 
-from pint import Context, DimensionalityError, UnitRegistry
+from pint import Context, DimensionalityError, UnitRegistry, get_application_registry
 from pint.compat import np
 from pint.testsuite import QuantityTestCase, helpers
 from pint.unit import UnitsContainer
@@ -775,6 +775,14 @@ class TestIssues(QuantityTestCase):
         with pytest.raises(DimensionalityError):
             2 ** ureg.Quantity([2, 3], "m")
 
+    def test_issue1175(self):
+        import pickle
+
+        foo1 = get_application_registry().Quantity(1, "s")
+        foo2 = pickle.loads(pickle.dumps(foo1))
+        self.assertIsInstance(foo1, foo2.__class__)
+        self.assertIsInstance(foo2, foo1.__class__)
+
 
 if np is not None: