Repository: hgrecco/pint

Issue:
Context redefinitions can't be overlayed
When multiple contexts are active and more than one redefines the same unit, pint incorrectly picks up the first redefinition instead of the latest:

```python
ureg = pint.UnitRegistry()
c1 = pint.Context.from_lines(["@context a", "lb = 0.5 kg"])
c2 = pint.Context.from_lines(["@context b", "lb = 0.7 kg"])
one_src = ureg.Quantity(1, "kg")
print(one_src.to("lb"))
ureg.enable_contexts(c1)
print(one_src.to("lb"))
ureg.enable_contexts(c2)
print(one_src.to("lb"))
```
Expected output:
```
2.2046226218487757 pound
2.0 pound
1.4285714285714286 pound
```
Actual output:
```
2.2046226218487757 pound
2.0 pound
2.0 pound
```

Inter-dimensional transforms instead work as expected:
```python
ureg = pint.UnitRegistry()
c1 = pint.Context.from_lines(["@context a", "[volume] -> [mass]: value * 1 kg/l"])
c2 = pint.Context.from_lines(["@context b", "[volume] -> [mass]: value * 2 kg/l"])
one_src = ureg.Quantity(1, "l")
ureg.enable_contexts(c1)
print(one_src.to("kg"))
ureg.enable_contexts(c2)
print(one_src.to("kg"))
```
Output:
```
1.0 kilogram
2.0 kilogram
```

Discussion:

Patch:
diff --git a/CHANGES b/CHANGES
index 8b4b3aa..6e67ea0 100644
--- a/CHANGES
+++ b/CHANGES
@@ -32,6 +32,8 @@ Pint Changelog
 - Fix typo in docs for wraps example with optional arguments. (Issue #1088)
 - Add momentum as a dimension
 - Fixed a bug where unit exponents were only partially superscripted in HTML format
+- Multiple contexts containing the same redefinition can now be stacked
+  (Issue #1108, Thanks Guido Imperiale)
 
 
 0.12 (2020-05-29)
diff --git a/pint/registry.py b/pint/registry.py
index 84544e1..ed6bb1d 100644
--- a/pint/registry.py
+++ b/pint/registry.py
@@ -1546,7 +1546,7 @@ class ContextRegistry(BaseRegistry):
         on_redefinition_backup = self._on_redefinition
         self._on_redefinition = "ignore"
         try:
-            for ctx in self._active_ctx.contexts:
+            for ctx in reversed(self._active_ctx.contexts):
                 for definition in ctx.redefinitions:
                     self._redefine(definition)
         finally:


Test patch:
diff --git a/pint/testsuite/test_contexts.py b/pint/testsuite/test_contexts.py
index bc575ed..b57a4df 100644
--- a/pint/testsuite/test_contexts.py
+++ b/pint/testsuite/test_contexts.py
@@ -835,6 +835,38 @@ class TestContextRedefinitions(QuantityTestCase):
             with ureg.context("mult_to_nonmult"):
                 self.assertAlmostEqual(k.to("bogodegrees").magnitude, (100 - 123) / 5)
 
+    def test_stack_contexts(self):
+        ureg = UnitRegistry(
+            """
+            a = [dim1]
+            b = 1/2 a
+            c = 1/3 a
+            d = [dim2]
+
+            @context c1
+                b = 1/4 a
+                c = 1/6 a
+                [dim1]->[dim2]: value * 2 d/a
+            @end
+            @context c2
+                b = 1/5 a
+                [dim1]->[dim2]: value * 3 d/a
+            @end
+            """.splitlines()
+        )
+        q = ureg.Quantity(1, "a")
+        assert q.to("b").magnitude == 2
+        assert q.to("c").magnitude == 3
+        assert q.to("b", "c1").magnitude == 4
+        assert q.to("c", "c1").magnitude == 6
+        assert q.to("d", "c1").magnitude == 2
+        assert q.to("b", "c2").magnitude == 5
+        assert q.to("c", "c2").magnitude == 3
+        assert q.to("d", "c2").magnitude == 3
+        assert q.to("b", "c1", "c2").magnitude == 5  # c2 takes precedence
+        assert q.to("c", "c1", "c2").magnitude == 6  # c2 doesn't change it, so use c1
+        assert q.to("d", "c1", "c2").magnitude == 3  # c2 takes precedence
+
     def test_err_to_base_unit(self):
         with self.assertRaises(DefinitionSyntaxError) as e:
             Context.from_lines(["@context c", "x = [d]"])