Repository: scipy/scipy

Issue:
DEP: remove tol from `NumericalInverseHermite`
Deprecated in https://github.com/scipy/scipy/pull/14703, warning does not [mention](https://github.com/scipy/scipy/blob/v1.8.0/scipy/stats/_unuran/unuran_wrapper.pyx.templ#L1717-L1719) a timeframe. Maybe the warning should be sharpened? Tentatively adding to 1.10 milestone.

CC @tirthasheshpatel 


Discussion:
Thanks for noticing @h-vetinari!

There is a (huge) cleanup pending for UNU.RAN. I am working on that (PR coming soon) and will include this as a part of the cleanup.
There are two more deprecations in stats module:

- `max_intervals` keyword for the `NumericalInverseHermite` method has been deprecated and will be removed in 1.10.0.
- `NumericalInverseHermite` method has been deprecated from the `scipy.stats` namespace and shifted to `scipy.stats.sampling`


Since there could be more of these in the future, an issue for each seems a bit too much (maybe start an issue to track all the deprecations in a module?). Another alternative I'd propose is to add these to a wiki page: more manageable and less noise in the issue tracker. What do you think @rgommers @tylerjereddy @h-vetinari?
> Since there could be more of these in the future, an issue for each seems a bit too much (maybe start an issue to track all the deprecations in a module?)

That's exactly what I was doing when I got called away. 😅 
I think it'd be good to have one for discussions about deprecation policy generally.

I'm fine with grouping things into issues where they make sense, but I don't think too coarse issues help, and the wiki isn't visible enough for my taste. IMO these issues need to be milestoned (i.e. where people look regularly), and tagged - where appropriate - with a "good first issue label".

But if people don't agree, I'll certainly stop - I just thought I'd do a trawl for DeprecationWarnings and file reminders for ourselves. 🙃 


Reopening this since #16198 only addresses the sharpen the warning part of the issue. The deprecation still needs to be executed later.
Just noticed that #15083 introduced another deprecation for `NumericalInverseHermite` that doesn't have a timeline yet:
```python
class NumericalInverseHermite:
    @_deprecated(
        "NumericalInverseHermite has been deprecated from `scipy.stats`. "
        " To use `NumericalInverseHermite`, import/use it from "
        "`scipy.stats.sampling` module instead. "
        "i.e. `from scipy.stats.sampling import NumericalInverseHermite`"
    )
    def __init__(self, *args, **kwargs):
```
> Just noticed that #15083 introduced another deprecation for `NumericalInverseHermite` that doesn't have a timeline yet:

Sharpened that deprecation in #16257 to mention removal in Scipy 1.10.
Thanks @h-vetinari 

Resolving patch:
diff --git a/scipy/stats/__init__.py b/scipy/stats/__init__.py
--- a/scipy/stats/__init__.py
+++ b/scipy/stats/__init__.py
@@ -479,7 +479,7 @@
 from ._resampling import bootstrap, monte_carlo_test, permutation_test
 from ._entropy import *
 from ._hypotests import *
-from ._rvs_sampling import rvs_ratio_uniforms, NumericalInverseHermite
+from ._rvs_sampling import rvs_ratio_uniforms
 from ._page_trend_test import page_trend_test
 from ._mannwhitneyu import mannwhitneyu
 from ._fit import fit
diff --git a/scipy/stats/_rvs_sampling.py b/scipy/stats/_rvs_sampling.py
--- a/scipy/stats/_rvs_sampling.py
+++ b/scipy/stats/_rvs_sampling.py
@@ -171,26 +171,3 @@ def rvs_ratio_uniforms(pdf, umax, vmin, vmax, size=1, c=0, random_state=None):
         i += 1
 
     return np.reshape(x, size1d)
-
-
-class NumericalInverseHermite:
-    @_deprecated(
-        "NumericalInverseHermite has been deprecated from `scipy.stats` "
-        "and will be removed in SciPy 1.10.0. "
-        " To use `NumericalInverseHermite`, import/use it from "
-        "`scipy.stats.sampling` module instead. "
-        "i.e. `from scipy.stats.sampling import NumericalInverseHermite`"
-    )
-    def __init__(self, *args, **kwargs):
-        self.hinv = unuran_wrapper.NumericalInverseHermite(*args, **kwargs)
-        self.intervals = self.hinv.intervals
-        self.midpoint_error = self.hinv.midpoint_error
-
-    def rvs(self, *args, **kwargs):
-        return self.hinv.rvs(*args, **kwargs)
-
-    def ppf(self, *args, **kwargs):
-        return self.hinv.ppf(*args, **kwargs)
-
-    def qrvs(self, *args, **kwargs):
-        return self.hinv.qrvs(*args, **kwargs)


Test patch:
diff --git a/scipy/stats/tests/test_sampling.py b/scipy/stats/tests/test_sampling.py
--- a/scipy/stats/tests/test_sampling.py
+++ b/scipy/stats/tests/test_sampling.py
@@ -1033,10 +1033,6 @@ def test_input_validation(self):
             NumericalInverseHermite(StandardNormal(),
                                     u_resolution='ekki')
 
-        match = "`max_intervals' must be..."
-        with pytest.raises(ValueError, match=match):
-            NumericalInverseHermite(StandardNormal(), max_intervals=-1)
-
     rngs = [None, 0, np.random.RandomState(0)]
     if NumpyVersion(np.__version__) >= '1.18.0':
         rngs.append(np.random.default_rng(0))  # type: ignore
@@ -1129,12 +1125,6 @@ def test_u_error(self):
         assert max_error < 1e-14
         assert mae <= max_error
 
-    def test_deprecations(self):
-        msg = ("`tol` has been deprecated and replaced with `u_resolution`. "
-               "It will be completely removed in SciPy 1.10.0.")
-        with pytest.warns(DeprecationWarning, match=msg):
-            NumericalInverseHermite(StandardNormal(), tol=1e-12)
-
 
 class TestDiscreteGuideTable:
     basic_fail_dists = {