Repository: statsmodels/statsmodels

Issue:
FAQ-D/MAINT Use FutureWarning instead of DeprecationWarning for user deprecation warning
(I'm late to the story, see pep-565 for python 3.7)

DeprecationWarnings are not displayed to users, e.g. don't show up in notebooks.
FutureWarnings are not silenced by default, and show up in notebooks.

Most of our deprecations affect the user directly, so they need to be FutureWarnings.

We might have to convert some DeprecationWarnings to FutureWarnings

for example
- predict `linear` is currently DeprecationWarnings  (in discrete, genmod, stats)
- recently added DeprecationWarnings in `stats`, 3 modules
- I don't know about DeprectionWarnings in tsa
- I didn't search for DeprecationWarnings that are indirectly through decorators


Discussion:

Patch:
diff --git a/statsmodels/discrete/discrete_model.py b/statsmodels/discrete/discrete_model.py
index 22e13e074..aa2723083 100644
--- a/statsmodels/discrete/discrete_model.py
+++ b/statsmodels/discrete/discrete_model.py
@@ -522,7 +522,7 @@ class BinaryModel(DiscreteModel):
         """
         if linear is not None:
             msg = 'linear keyword is deprecated, use which="linear"'
-            warnings.warn(msg, DeprecationWarning)
+            warnings.warn(msg, FutureWarning)
             if linear is True:
                 which = "linear"
 
@@ -752,7 +752,7 @@ class MultinomialModel(BinaryModel):
         """
         if linear is not None:
             msg = 'linear keyword is deprecated, use which="linear"'
-            warnings.warn(msg, DeprecationWarning)
+            warnings.warn(msg, FutureWarning)
             if linear is True:
                 which = "linear"
 
@@ -1012,7 +1012,7 @@ class CountModel(DiscreteModel):
         """
         if linear is not None:
             msg = 'linear keyword is deprecated, use which="linear"'
-            warnings.warn(msg, DeprecationWarning)
+            warnings.warn(msg, FutureWarning)
             if linear is True:
                 which = "linear"
 
@@ -1634,7 +1634,7 @@ class Poisson(CountModel):
 
         if linear is not None:
             msg = 'linear keyword is deprecated, use which="linear"'
-            warnings.warn(msg, DeprecationWarning)
+            warnings.warn(msg, FutureWarning)
             if linear is True:
                 which = "linear"
 
@@ -3584,7 +3584,7 @@ class NegativeBinomial(CountModel):
 
         if linear is not None:
             msg = 'linear keyword is deprecated, use which="linear"'
-            warnings.warn(msg, DeprecationWarning)
+            warnings.warn(msg, FutureWarning)
             if linear is True:
                 which = "linear"
 
diff --git a/statsmodels/genmod/generalized_linear_model.py b/statsmodels/genmod/generalized_linear_model.py
index fe520803c..c0799b3d7 100644
--- a/statsmodels/genmod/generalized_linear_model.py
+++ b/statsmodels/genmod/generalized_linear_model.py
@@ -897,7 +897,7 @@ class GLM(base.LikelihoodModel):
         """
         if linear is not None:
             msg = 'linear keyword is deprecated, use which="linear"'
-            warnings.warn(msg, DeprecationWarning)
+            warnings.warn(msg, FutureWarning)
             if linear is True:
                 which = "linear"
 
diff --git a/statsmodels/sandbox/stats/runs.py b/statsmodels/sandbox/stats/runs.py
index e431b989d..d80051c8a 100644
--- a/statsmodels/sandbox/stats/runs.py
+++ b/statsmodels/sandbox/stats/runs.py
@@ -477,7 +477,7 @@ def cochrans_q(x):
 
     '''
 
-    warnings.warn("Deprecated, use stats.cochrans_q instead", DeprecationWarning)
+    warnings.warn("Deprecated, use stats.cochrans_q instead", FutureWarning)
 
     x = np.asarray(x)
     gruni = np.unique(x)
@@ -539,7 +539,7 @@ def mcnemar(x, y=None, exact=True, correction=True):
 
     '''
 
-    warnings.warn("Deprecated, use stats.TableSymmetry instead", DeprecationWarning)
+    warnings.warn("Deprecated, use stats.TableSymmetry instead", FutureWarning)
 
     x = np.asarray(x)
     if y is None and x.shape[0] == x.shape[1]:
@@ -605,7 +605,7 @@ def symmetry_bowker(table):
 
     '''
 
-    warnings.warn("Deprecated, use stats.TableSymmetry instead", DeprecationWarning)
+    warnings.warn("Deprecated, use stats.TableSymmetry instead", FutureWarning)
 
     table = np.asarray(table)
     k, k2 = table.shape
diff --git a/statsmodels/stats/_diagnostic_other.py b/statsmodels/stats/_diagnostic_other.py
index 38e77fbb6..773d3b898 100644
--- a/statsmodels/stats/_diagnostic_other.py
+++ b/statsmodels/stats/_diagnostic_other.py
@@ -203,7 +203,7 @@ def dispersion_poisson(results):
        alternative hypothesis.
     """
     msg = 'dispersion_poisson here is deprecated, use '
-    warnings.warn(msg, DeprecationWarning)
+    warnings.warn(msg, FutureWarning)
 
     from statsmodels.discrete._diagnostics_count import test_poisson_dispersion
     return test_poisson_dispersion(results, _old=True)
@@ -226,7 +226,7 @@ def dispersion_poisson_generic(results, exog_new_test, exog_new_control=None,
     Warning: insufficiently tested, especially for options
     """
     msg = 'dispersion_poisson here is deprecated, use '
-    warnings.warn(msg, DeprecationWarning)
+    warnings.warn(msg, FutureWarning)
 
     from statsmodels.discrete._diagnostics_count import (
         _test_poisson_dispersion_generic
diff --git a/statsmodels/stats/outliers_influence.py b/statsmodels/stats/outliers_influence.py
index bc4c54884..7058adaa1 100644
--- a/statsmodels/stats/outliers_influence.py
+++ b/statsmodels/stats/outliers_influence.py
@@ -609,7 +609,7 @@ class MLEInfluence(_BaseInfluenceMixin):
         with warnings.catch_warnings():
             msg = 'linear keyword is deprecated, use which="linear"'
             warnings.filterwarnings("ignore", message=msg,
-                                    category=DeprecationWarning)
+                                    category=FutureWarning)
             pred = self.results.get_prediction()
         return pred
 
diff --git a/statsmodels/stats/rates.py b/statsmodels/stats/rates.py
index 6960be6f0..9f0284340 100644
--- a/statsmodels/stats/rates.py
+++ b/statsmodels/stats/rates.py
@@ -752,7 +752,7 @@ def test_poisson_2indep(count1, exposure1, count2, exposure2, value=None,
             value = ratio_null = 1
         elif ratio_null is not None:
             warnings.warn("'ratio_null' is deprecated, use 'value' keyword",
-                          DeprecationWarning)
+                          FutureWarning)
             value = ratio_null
         else:
             # for results holder instance, it still contains ratio_null
@@ -979,7 +979,7 @@ def etest_poisson_2indep(count1, exposure1, count2, exposure2, ratio_null=None,
             value = 1
         elif ratio_null is not None:
             warnings.warn("'ratio_null' is deprecated, use 'value' keyword",
-                          DeprecationWarning)
+                          FutureWarning)
             value = ratio_null
 
         r = value  # rate1 / rate2
@@ -1037,7 +1037,7 @@ def etest_poisson_2indep(count1, exposure1, count2, exposure2, ratio_null=None,
     stat_sample = stat_func(y1, y2)
 
     if ygrid is not None:
-        warnings.warn("ygrid is deprecated, use y_grid", DeprecationWarning)
+        warnings.warn("ygrid is deprecated, use y_grid", FutureWarning)
     y_grid = y_grid if y_grid is not None else ygrid
 
     # The following uses a fixed truncation for evaluating the probabilities
diff --git a/statsmodels/tsa/base/tsa_model.py b/statsmodels/tsa/base/tsa_model.py
index 9977f4b0f..a14628d87 100644
--- a/statsmodels/tsa/base/tsa_model.py
+++ b/statsmodels/tsa/base/tsa_model.py
@@ -433,7 +433,7 @@ def get_prediction_index(
                 " version, calling this method in a model"
                 " without a supported index will result in an"
                 " exception.",
-                DeprecationWarning,
+                FutureWarning,
                 stacklevel=2,
             )
     elif index_none:
diff --git a/statsmodels/tsa/statespace/simulation_smoother.py b/statsmodels/tsa/statespace/simulation_smoother.py
index c2872d645..0d86d6bc2 100644
--- a/statsmodels/tsa/statespace/simulation_smoother.py
+++ b/statsmodels/tsa/statespace/simulation_smoother.py
@@ -626,7 +626,7 @@ class SimulationSmoothResults:
             msg = ('`disturbance_variates` keyword is deprecated, use'
                    ' `measurement_disturbance_variates` and'
                    ' `state_disturbance_variates` instead.')
-            warnings.warn(msg, DeprecationWarning)
+            warnings.warn(msg, FutureWarning)
             if (measurement_disturbance_variates is not None
                     or state_disturbance_variates is not None):
                 raise ValueError('Cannot use `disturbance_variates` in'
@@ -642,7 +642,7 @@ class SimulationSmoothResults:
             msg = ('`pretransformed` keyword is deprecated, use'
                    ' `pretransformed_measurement_disturbance_variates` and'
                    ' `pretransformed_state_disturbance_variates` instead.')
-            warnings.warn(msg, DeprecationWarning)
+            warnings.warn(msg, FutureWarning)
             if (pretransformed_measurement_disturbance_variates is not None
                     or pretransformed_state_disturbance_variates is not None):
                 raise ValueError(


Test patch:
diff --git a/statsmodels/genmod/tests/test_glm.py b/statsmodels/genmod/tests/test_glm.py
index efe87aa7e..9c81dc007 100644
--- a/statsmodels/genmod/tests/test_glm.py
+++ b/statsmodels/genmod/tests/test_glm.py
@@ -990,7 +990,7 @@ class TestGlmPoissonOffset(CheckModelResultsMixin):
         # Check that offset shifts the linear predictor
         mod3 = GLM(endog, exog, family=sm.families.Poisson()).fit()
         offset = np.random.uniform(1, 2, 10)
-        with pytest.warns(DeprecationWarning):
+        with pytest.warns(FutureWarning):
             # deprecation warning for linear keyword
             pred1 = mod3.predict(exog=exog1, offset=offset, linear=True)
         pred2 = mod3.predict(exog=exog1, offset=2*offset, which="linear")
diff --git a/statsmodels/stats/tests/test_nonparametric.py b/statsmodels/stats/tests/test_nonparametric.py
index 62ea81083..5d874b437 100644
--- a/statsmodels/stats/tests/test_nonparametric.py
+++ b/statsmodels/stats/tests/test_nonparametric.py
@@ -92,22 +92,22 @@ def test_mcnemar_chisquare():
 
 def test_mcnemar_vectorized(reset_randomstate):
     ttk = np.random.randint(5,15, size=(2,2,3))
-    with pytest.deprecated_call():
+    with pytest.warns(FutureWarning):
         res = sbmcnemar(ttk, exact=False)
-    with pytest.deprecated_call():
+    with pytest.warns(FutureWarning):
         res1 = lzip(*[sbmcnemar(ttk[:, :, i], exact=False) for i in range(3)])
     assert_allclose(res, res1, rtol=1e-13)
 
-    with pytest.deprecated_call():
+    with pytest.warns(FutureWarning):
         res = sbmcnemar(ttk, exact=False, correction=False)
-    with pytest.deprecated_call():
+    with pytest.warns(FutureWarning):
         res1 = lzip(*[sbmcnemar(ttk[:, :, i], exact=False, correction=False)
                       for i in range(3)])
     assert_allclose(res, res1, rtol=1e-13)
 
-    with pytest.deprecated_call():
+    with pytest.warns(FutureWarning):
         res = sbmcnemar(ttk, exact=True)
-    with pytest.deprecated_call():
+    with pytest.warns(FutureWarning):
         res1 = lzip(*[sbmcnemar(ttk[:, :, i], exact=True) for i in range(3)])
     assert_allclose(res, res1, rtol=1e-13)
 
@@ -171,7 +171,7 @@ def test_cochransq():
     #equivalence of mcnemar and cochranq for 2 samples
     a,b = x[:,:2].T
     res = cochrans_q(x[:, :2])
-    with pytest.deprecated_call():
+    with pytest.warns(FutureWarning):
         assert_almost_equal(sbmcnemar(a, b, exact=False, correction=False),
                             [res.statistic, res.pvalue])
 
diff --git a/statsmodels/stats/tests/test_rates_poisson.py b/statsmodels/stats/tests/test_rates_poisson.py
index c930bee3a..30bc0f789 100644
--- a/statsmodels/stats/tests/test_rates_poisson.py
+++ b/statsmodels/stats/tests/test_rates_poisson.py
@@ -360,7 +360,7 @@ def test_twosample_poisson():
     assert_allclose(pv2, pv2r*2, rtol=0, atol=5e-4)
     assert_allclose(s2, 0.7056, atol=0, rtol=5e-4)
 
-    with pytest.warns(DeprecationWarning):
+    with pytest.warns(FutureWarning):
         s2, pv2 = smr.test_poisson_2indep(count1, n1, count2, n2,
                                           method='score-log', ratio_null=1.5)
     pv2r = 0.2303
@@ -831,7 +831,7 @@ def test_invalid_y_grid():
     with warnings.catch_warnings(record=True) as w:
         etest_poisson_2indep(1, 1, 1, 1, ygrid=[1])
     assert len(w) == 1
-    assert issubclass(w[0].category, DeprecationWarning)
+    assert issubclass(w[0].category, FutureWarning)
     assert "ygrid" in str(w[0].message)
 
     # check y_grid validity
diff --git a/statsmodels/tsa/statespace/tests/test_simulation_smoothing.py b/statsmodels/tsa/statespace/tests/test_simulation_smoothing.py
index fe601d000..b8b6dafd5 100644
--- a/statsmodels/tsa/statespace/tests/test_simulation_smoothing.py
+++ b/statsmodels/tsa/statespace/tests/test_simulation_smoothing.py
@@ -710,7 +710,7 @@ def test_deprecated_arguments_univariate():
                  initial_state_variates=np.zeros(1))
     desired = sim.simulated_state[0]
 
-    with pytest.deprecated_call():
+    with pytest.warns(FutureWarning):
         sim.simulate(disturbance_variates=np.r_[mds, sds],
                      initial_state_variates=np.zeros(1))
     actual = sim.simulated_state[0]
@@ -724,7 +724,7 @@ def test_deprecated_arguments_univariate():
                  pretransformed_state_disturbance_variates=True)
     desired = sim.simulated_state[0]
 
-    with pytest.deprecated_call():
+    with pytest.warns(FutureWarning):
         sim.simulate(measurement_disturbance_variates=mds,
                      state_disturbance_variates=sds,
                      pretransformed=True,
@@ -756,7 +756,7 @@ def test_deprecated_arguments_multivariate():
                  initial_state_variates=np.zeros(2))
     desired = sim.simulated_state[0]
 
-    with pytest.deprecated_call():
+    with pytest.warns(FutureWarning):
         sim.simulate(disturbance_variates=np.r_[mds.ravel(), sds.ravel()],
                      initial_state_variates=np.zeros(2))
     actual = sim.simulated_state[0]
@@ -770,7 +770,7 @@ def test_deprecated_arguments_multivariate():
                  pretransformed_state_disturbance_variates=True)
     desired = sim.simulated_state[0]
 
-    with pytest.deprecated_call():
+    with pytest.warns(FutureWarning):
         sim.simulate(measurement_disturbance_variates=mds,
                      state_disturbance_variates=sds,
                      pretransformed=True,