Repository: hgrecco/pint-pandas (language: python)

Issue:
pint-pandas having problems with the new pint release
`pint` released a new version `0.21` and pint-pandas is having problems when you try to import it `AttributeError: module 'pint.compat' has no attribute 'upcast_types'`
pint 0.21 and nanops support
This PR tries to support `pint 0.21`. This PR also considers a strange behavior that was not appreciated in minor pandas versions. 

The module `pandas.core.nanops` is supposed to act on numpy ndarrays, that's why in the test `TestGroupby.test_in_numeric_groupby` we were getting the index containing the column `"C"` only. Minor pandas versions were not raising errors and they were just omitting the column passed to the `nanops` functions, but now `pandas >=1.5.3` is raising error. To solve this i added a `numpy_data` property that tries to pass numpy ndarrays to the `nanops` functions







Delegate to reduce
- [ ] Closes # (insert issue number)
- [ ] Executed ``pre-commit run --all-files`` with no errors
- [ ] The change is fully covered by automated unit tests
- [ ] Documented in docs/ as appropriate
- [ ] Added an entry to the CHANGES file



Discussion / hints:
If you delete the last line of the file pint_array.py (which calls compat.upcast_types) it might just work.  It does for me.
I stumbled across this message after I figured out that commenting the last line in pint_array.py (line 995) indeed works.
This solution is a good work-around when doing local development, but in a CI pipeline where these dependencies are being installed and then immediately used (no human involved), this is not a useful work-around. Any other ideas? Like, if I lock down to a specific version of `pint`, which one should I use?

EDIT: looks like using this in a requirements.txt suffices to get my automation running again: `pint<0.21`
Seems to be related to this commit in pint: https://github.com/hgrecco/pint/commit/77ff32a8e31164a9eedc4170924579b2911ed19e where the structure of pint's pandas integration was changed, and appending to `upcast_types` is not necessary any more to get pint-pandas working properly. So probably pint-pandas needs to support both the old way of integration and the new way?
xref https://github.com/pandas-dev/pandas/issues/50564

I'm not saying tha this issue needs to fix the pandas problem I reported, but I was going to look back into it and noticed that things are in flux.  When less in flux, I'll look harder.
I'm not sure why in the actions we are getting the pandas from
```
pandas: ["git+https://github.com/andrewgsavage/pandas.git@assert_1_5",
"git+https://github.com/andrewgsavage/pandas.git@assert_almost_equal", ]
```
Looking at the logs of my PR seems that it installed a dev version of pandas 0.24.0
```
Installing collected packages: pandas
  Attempting uninstall: pandas
    Found existing installation: pandas 2.0.1
    Uninstalling pandas-2.0.1:
      Successfully uninstalled pandas-2.0.1
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
pint-pandas 0.4.dev156+g27270a6 requires pandas>=1.5, but you have pandas 0.24.0.dev0+13114.g7380206be which is incompatible.
Successfully installed pandas-0.24.0.dev0+13114.g7380206be

```
I changed the pandas matrix to test on pandas >= 1.5.0






Fix patch:
diff --git a/CHANGES b/CHANGES
index a9292d8..cf36689 100644
--- a/CHANGES
+++ b/CHANGES
@@ -6,7 +6,7 @@ pint-pandas Changelog
 
 - Support for <NA> values in columns with integer magnitudes 
 - Support for magnitudes of any type, such as complex128 or tuples #146
-- Support for Pint 0.21 #168
+- Support for Pint 0.21 #168, #179
 
 0.3 (2022-11-14)
 ----------------
diff --git a/pint_pandas/pint_array.py b/pint_pandas/pint_array.py
index de1cb81..d8349cc 100644
--- a/pint_pandas/pint_array.py
+++ b/pint_pandas/pint_array.py
@@ -1037,6 +1037,7 @@ def is_pint_type(obj):
     # for pint < 0.21 we need to explicitly register
     compat.upcast_types.append(PintArray)
 except AttributeError:
-    # for pint = 0.21 we need to add the full name, which is to be added in pint > 0.21
-    compat.upcast_type_map.setdefault("pint_pandas.pint_array.PintArray", None)
-    pass
+    # for pint = 0.21 we need to add the full names of PintArray and DataFrame,
+    # which is to be added in pint > 0.21
+    compat.upcast_type_map.setdefault("pint_pandas.pint_array.PintArray", PintArray)
+    compat.upcast_type_map.setdefault("pandas.core.frame.DataFrame", DataFrame)


Test patch:
diff --git a/pint_pandas/testsuite/test_pandas_extensiontests.py b/pint_pandas/testsuite/test_pandas_extensiontests.py
index 3236ade..ce15e57 100644
--- a/pint_pandas/testsuite/test_pandas_extensiontests.py
+++ b/pint_pandas/testsuite/test_pandas_extensiontests.py
@@ -313,7 +313,6 @@ def test_groupby_extension_no_sort(self, data_for_grouping):
 
 
 class TestInterface(base.BaseInterfaceTests):
-    @pytest.mark.xfail(run=True, reason="incompatible with Pint 0.21")
     def test_contains(self, data, data_missing):
         base.BaseInterfaceTests.test_contains(self, data, data_missing)
 
@@ -352,7 +351,6 @@ def _get_exception(self, data, op_name):
     def test_divmod_series_array(self, data, data_for_twos):
         base.BaseArithmeticOpsTests.test_divmod_series_array(self, data, data_for_twos)
 
-    @pytest.mark.xfail(run=True, reason="incompatible with Pint 0.21")
     def test_arith_series_with_scalar(self, data, all_arithmetic_operators):
         # With Pint 0.21, series and scalar need to have compatible units for
         # the arithmetic to work
@@ -367,7 +365,6 @@ def test_arith_series_with_array(self, data, all_arithmetic_operators):
         ser = pd.Series(data)
         self.check_opname(ser, op_name, pd.Series([ser.iloc[0]] * len(ser)), exc)
 
-    @pytest.mark.xfail(run=True, reason="incompatible with Pint 0.21")
     def test_arith_frame_with_scalar(self, data, all_arithmetic_operators):
         # frame & scalar
         op_name, exc = self._get_exception(data, all_arithmetic_operators)
@@ -396,7 +393,6 @@ def test_compare_scalar(self, data, all_compare_operators):
         other = data[0]
         self._compare_other(s, data, op_name, other)
 
-    @pytest.mark.xfail(run=True, reason="incompatible with Pint 0.21")
     def test_compare_array(self, data, all_compare_operators):
         # nb this compares an quantity containing array
         # eg Q_([1,2],"m")