Repository: pandas-dev/pandas

Issue:
BUG: in error message raised when invalid axis parameter
#### Code Sample, a copy-pastable example if possible

```python
import numpy as np
from pandas import DataFrame
df = DataFrame(np.random.randn(6, 4))
df.dropna(axis=3)
```
#### Problem description

0.25.0.dev0+198.gd10bbce34
```python-traceback
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\simon\OneDrive\code\pandas-simonjayhawkins\pandas\core\frame.py", line 4575, in dropna
    axis = self._get_axis_number(axis)
  File "C:\Users\simon\OneDrive\code\pandas-simonjayhawkins\pandas\core\generic.py", line 361, in _get_axis_number
    .format(axis, type(cls)))
ValueError: No axis named 3 for object type <class 'type'>
```

0.23.4:
```python-traceback
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-2-5ab8608d1d61> in <module>
      2 from pandas import DataFrame
      3 df = DataFrame(np.random.randn(6, 4))
----> 4 df.dropna(axis=3)

~\Anaconda3\lib\site-packages\pandas\core\frame.py in dropna(self, axis, how, thresh, subset, inplace)
   4274                                        axis=ax)
   4275         else:
-> 4276             axis = self._get_axis_number(axis)
   4277             agg_axis = 1 - axis
   4278 

~\Anaconda3\lib\site-packages\pandas\core\generic.py in _get_axis_number(self, axis)
    373                 pass
    374         raise ValueError('No axis named {0} for object type {1}'
--> 375                          .format(axis, type(self)))
    376 
    377     def _get_axis_name(self, axis):

ValueError: No axis named 3 for object type <class 'pandas.core.frame.DataFrame'>
```
#### Expected Output

#### Output of ``pd.show_versions()``

<details>

[paste the output of ``pd.show_versions()`` here below this line]

</details>



Discussion:

Resolving patch:
diff --git a/pandas/core/generic.py b/pandas/core/generic.py
--- a/pandas/core/generic.py
+++ b/pandas/core/generic.py
@@ -358,7 +358,7 @@ def _get_axis_number(cls, axis):
             except KeyError:
                 pass
         raise ValueError('No axis named {0} for object type {1}'
-                         .format(axis, type(cls)))
+                         .format(axis, cls))
 
     @classmethod
     def _get_axis_name(cls, axis):
@@ -372,7 +372,7 @@ def _get_axis_name(cls, axis):
             except KeyError:
                 pass
         raise ValueError('No axis named {0} for object type {1}'
-                         .format(axis, type(cls)))
+                         .format(axis, cls))
 
     def _get_axis(self, axis):
         name = self._get_axis_name(axis)


Test patch:
diff --git a/pandas/tests/frame/test_analytics.py b/pandas/tests/frame/test_analytics.py
--- a/pandas/tests/frame/test_analytics.py
+++ b/pandas/tests/frame/test_analytics.py
@@ -1385,7 +1385,8 @@ def test_idxmin(self, float_frame, int_frame):
                                         skipna=skipna)
                     tm.assert_series_equal(result, expected)
 
-        msg = "No axis named 2 for object type <class 'type'>"
+        msg = ("No axis named 2 for object type"
+               " <class 'pandas.core.frame.DataFrame'>")
         with pytest.raises(ValueError, match=msg):
             frame.idxmin(axis=2)
 
@@ -1402,7 +1403,8 @@ def test_idxmax(self, float_frame, int_frame):
                                         skipna=skipna)
                     tm.assert_series_equal(result, expected)
 
-        msg = "No axis named 2 for object type <class 'type'>"
+        msg = ("No axis named 2 for object type"
+               " <class 'pandas.core.frame.DataFrame'>")
         with pytest.raises(ValueError, match=msg):
             frame.idxmax(axis=2)
 
diff --git a/pandas/tests/frame/test_api.py b/pandas/tests/frame/test_api.py
--- a/pandas/tests/frame/test_api.py
+++ b/pandas/tests/frame/test_api.py
@@ -366,7 +366,8 @@ def test_swapaxes(self):
         self._assert_frame_equal(df.T, df.swapaxes(0, 1))
         self._assert_frame_equal(df.T, df.swapaxes(1, 0))
         self._assert_frame_equal(df, df.swapaxes(0, 0))
-        msg = "No axis named 2 for object type <class 'type'>"
+        msg = ("No axis named 2 for object type"
+               r" <class 'pandas.core(.sparse)?.frame.(Sparse)?DataFrame'>")
         with pytest.raises(ValueError, match=msg):
             df.swapaxes(2, 5)
 
diff --git a/pandas/tests/frame/test_axis_select_reindex.py b/pandas/tests/frame/test_axis_select_reindex.py
--- a/pandas/tests/frame/test_axis_select_reindex.py
+++ b/pandas/tests/frame/test_axis_select_reindex.py
@@ -1067,7 +1067,8 @@ def test_reindex_axis(self):
         reindexed2 = self.intframe.reindex(index=rows)
         assert_frame_equal(reindexed1, reindexed2)
 
-        msg = "No axis named 2 for object type <class 'type'>"
+        msg = ("No axis named 2 for object type"
+               " <class 'pandas.core.frame.DataFrame'>")
         with pytest.raises(ValueError, match=msg):
             self.intframe.reindex_axis(rows, axis=2)
 
diff --git a/pandas/tests/frame/test_missing.py b/pandas/tests/frame/test_missing.py
--- a/pandas/tests/frame/test_missing.py
+++ b/pandas/tests/frame/test_missing.py
@@ -140,7 +140,8 @@ def test_dropna(self):
         assert_frame_equal(dropped, expected)
 
         # bad input
-        msg = "No axis named 3 for object type <class 'type'>"
+        msg = ("No axis named 3 for object type"
+               " <class 'pandas.core.frame.DataFrame'>")
         with pytest.raises(ValueError, match=msg):
             df.dropna(axis=3)
 
diff --git a/pandas/tests/frame/test_quantile.py b/pandas/tests/frame/test_quantile.py
--- a/pandas/tests/frame/test_quantile.py
+++ b/pandas/tests/frame/test_quantile.py
@@ -95,10 +95,12 @@ def test_quantile_axis_parameter(self):
         result = df.quantile(.5, axis="columns")
         assert_series_equal(result, expected)
 
-        msg = "No axis named -1 for object type <class 'type'>"
+        msg = ("No axis named -1 for object type"
+               " <class 'pandas.core.frame.DataFrame'>")
         with pytest.raises(ValueError, match=msg):
             df.quantile(0.1, axis=-1)
-        msg = "No axis named column for object type <class 'type'>"
+        msg = ("No axis named column for object type"
+               " <class 'pandas.core.frame.DataFrame'>")
         with pytest.raises(ValueError, match=msg):
             df.quantile(0.1, axis="column")
 
diff --git a/pandas/tests/frame/test_sorting.py b/pandas/tests/frame/test_sorting.py
--- a/pandas/tests/frame/test_sorting.py
+++ b/pandas/tests/frame/test_sorting.py
@@ -55,7 +55,8 @@ def test_sort_values(self):
         sorted_df = frame.sort_values(by=['B', 'A'], ascending=[True, False])
         assert_frame_equal(sorted_df, expected)
 
-        msg = "No axis named 2 for object type <class 'type'>"
+        msg = ("No axis named 2 for object type"
+               " <class 'pandas.core.frame.DataFrame'>")
         with pytest.raises(ValueError, match=msg):
             frame.sort_values(by=['A', 'B'], axis=2, inplace=True)
 
diff --git a/pandas/tests/frame/test_timeseries.py b/pandas/tests/frame/test_timeseries.py
--- a/pandas/tests/frame/test_timeseries.py
+++ b/pandas/tests/frame/test_timeseries.py
@@ -862,7 +862,8 @@ def test_frame_to_period(self):
         pts = df.to_period('M', axis=1)
         tm.assert_index_equal(pts.columns, exp.columns.asfreq('M'))
 
-        msg = "No axis named 2 for object type <class 'type'>"
+        msg = ("No axis named 2 for object type"
+               " <class 'pandas.core.frame.DataFrame'>")
         with pytest.raises(ValueError, match=msg):
             df.to_period(axis=2)
 
diff --git a/pandas/tests/series/test_analytics.py b/pandas/tests/series/test_analytics.py
--- a/pandas/tests/series/test_analytics.py
+++ b/pandas/tests/series/test_analytics.py
@@ -771,6 +771,7 @@ def test_isin_empty(self, empty):
         result = s.isin(empty)
         tm.assert_series_equal(expected, result)
 
+    @pytest.mark.skipif(PY2, reason="pytest.raises match regex fails")
     def test_ptp(self):
         # GH21614
         N = 1000
@@ -796,7 +797,8 @@ def test_ptp(self):
         with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
             tm.assert_series_equal(s.ptp(level=0, skipna=False), expected)
 
-        msg = r"No axis named 1 for object type <(class|type) 'type'>"
+        msg = ("No axis named 1 for object type"
+               " <class 'pandas.core.series.Series'>")
         with pytest.raises(ValueError, match=msg):
             with tm.assert_produces_warning(FutureWarning,
                                             check_stacklevel=False):
diff --git a/pandas/tests/series/test_missing.py b/pandas/tests/series/test_missing.py
--- a/pandas/tests/series/test_missing.py
+++ b/pandas/tests/series/test_missing.py
@@ -10,7 +10,7 @@
 import pytz
 
 from pandas._libs.tslib import iNaT
-from pandas.compat import range
+from pandas.compat import PY2, range
 from pandas.errors import PerformanceWarning
 import pandas.util._test_decorators as td
 
@@ -654,6 +654,7 @@ def test_timedelta64_nan(self):
         #     expected = (datetime_series >= -0.5) & (datetime_series <= 0.5)
         #     assert_series_equal(selector, expected)
 
+    @pytest.mark.skipif(PY2, reason="pytest.raises match regex fails")
     def test_dropna_empty(self):
         s = Series([])
         assert len(s.dropna()) == 0
@@ -661,7 +662,8 @@ def test_dropna_empty(self):
         assert len(s) == 0
 
         # invalid axis
-        msg = r"No axis named 1 for object type <(class|type) 'type'>"
+        msg = ("No axis named 1 for object type"
+               " <class 'pandas.core.series.Series'>")
         with pytest.raises(ValueError, match=msg):
             s.dropna(axis=1)
 
diff --git a/pandas/tests/series/test_rank.py b/pandas/tests/series/test_rank.py
--- a/pandas/tests/series/test_rank.py
+++ b/pandas/tests/series/test_rank.py
@@ -9,7 +9,7 @@
 from pandas._libs.algos import Infinity, NegInfinity
 from pandas._libs.tslib import iNaT
 import pandas.compat as compat
-from pandas.compat import product
+from pandas.compat import PY2, product
 import pandas.util._test_decorators as td
 
 from pandas import NaT, Series, Timestamp, date_range
@@ -203,10 +203,12 @@ def test_rank_categorical(self):
         assert_series_equal(na_ser.rank(na_option='bottom', pct=True), exp_bot)
         assert_series_equal(na_ser.rank(na_option='keep', pct=True), exp_keep)
 
+    @pytest.mark.skipif(PY2, reason="pytest.raises match regex fails")
     def test_rank_signature(self):
         s = Series([0, 1])
         s.rank(method='average')
-        msg = r"No axis named average for object type <(class|type) 'type'>"
+        msg = ("No axis named average for object type"
+               " <class 'pandas.core.series.Series'>")
         with pytest.raises(ValueError, match=msg):
             s.rank('average')
 
diff --git a/pandas/tests/series/test_sorting.py b/pandas/tests/series/test_sorting.py
--- a/pandas/tests/series/test_sorting.py
+++ b/pandas/tests/series/test_sorting.py
@@ -5,6 +5,8 @@
 import numpy as np
 import pytest
 
+from pandas.compat import PY2
+
 from pandas import Categorical, DataFrame, IntervalIndex, MultiIndex, Series
 import pandas.util.testing as tm
 from pandas.util.testing import assert_almost_equal, assert_series_equal
@@ -88,6 +90,7 @@ def test_sort_values(self):
         with pytest.raises(ValueError, match=msg):
             s.sort_values(inplace=True)
 
+    @pytest.mark.skipif(PY2, reason="pytest.raises match regex fails")
     def test_sort_index(self):
         rindex = list(self.ts.index)
         random.shuffle(rindex)
@@ -109,7 +112,8 @@ def test_sort_index(self):
         sorted_series = random_order.sort_index(axis=0)
         assert_series_equal(sorted_series, self.ts)
 
-        msg = r"No axis named 1 for object type <(class|type) 'type'>"
+        msg = ("No axis named 1 for object type"
+               " <class 'pandas.core.series.Series'>")
         with pytest.raises(ValueError, match=msg):
             random_order.sort_values(axis=1)
 
diff --git a/pandas/tests/series/test_timeseries.py b/pandas/tests/series/test_timeseries.py
--- a/pandas/tests/series/test_timeseries.py
+++ b/pandas/tests/series/test_timeseries.py
@@ -8,7 +8,7 @@
 
 from pandas._libs.tslib import iNaT
 from pandas._libs.tslibs.np_datetime import OutOfBoundsDatetime
-from pandas.compat import StringIO, lrange, product
+from pandas.compat import PY2, StringIO, lrange, product
 from pandas.errors import NullFrequencyError
 import pandas.util._test_decorators as td
 
@@ -867,6 +867,7 @@ def test_between_time_formats(self):
         for time_string in strings:
             assert len(ts.between_time(*time_string)) == expected_length
 
+    @pytest.mark.skipif(PY2, reason="pytest.raises match regex fails")
     def test_between_time_axis(self):
         # issue 8839
         rng = date_range('1/1/2000', periods=100, freq='10min')
@@ -876,7 +877,8 @@ def test_between_time_axis(self):
 
         assert len(ts.between_time(stime, etime)) == expected_length
         assert len(ts.between_time(stime, etime, axis=0)) == expected_length
-        msg = r"No axis named 1 for object type <(class|type) 'type'>"
+        msg = ("No axis named 1 for object type"
+               " <class 'pandas.core.series.Series'>")
         with pytest.raises(ValueError, match=msg):
             ts.between_time(stime, etime, axis=1)