Repository: statsmodels/statsmodels

Issue:
Error catching in grangercausalitytest
When passing a zero lag to `grangercausalitytests` in a list, such as in:

```python
granger = grangercausalitytests(df, maxlag=[0, 5, 10])
```

The expected behavior would be raising an exception (line 1197 of stattools.py):

```python
try:
        lags = np.array([int(lag) for lag in maxlag])
        maxlag = lags.max()
        if lags.min() <= 0 or lags.size == 0:
            raise ValueError('maxlag must be a non-empty list containing only '
                             'positive integers')
    except Exception:
        maxlag = int_like(maxlag, 'maxlag')
        if maxlag <= 0:
            raise ValueError('maxlag must a a positive integer')
        lags = np.arange(1, maxlag + 1)
```

However, this exception seems to be catched by the `except Exception` and pass `maxlag` (which now has the value of `lags.max()`) to `int_like`, as a result, the calculation is performed for all the lags from 1 to `maxlag.max()`. 

I think this could be fixed just by changing the `except Except` by `except TypeError`.

I can try and fix this myself, if that is ok.

thank you,



Discussion:
I agree, but I think the fix would be to invert it, with the int_like first, and then except TypeError to get the list version. It would be great if you could do a PR.
you mean doing something like this:

```python
try:
    max_lag = int_like(maxlag, 'maxlag')
    ...
except TypeError:
    lags = np.array ...
    ....
```

I guess that is actually better. I was just looking inside the `int_like` code to make sure under which circumstances it will raise a `TypeError` exception,  because I was thinking about the possibility of the user passing a float by mistake, but then I noticed the `strict` parameter is False by default, so I think this will work just fine.

This will be my first PR, so will take me some time to learn the workflow, but I would love to give it a try.

I think this should go on a different issue, but I think it could be nice if the user could select one of the four methods to calculate the Granger causality, so that in situations where you are calculating on large datasets that can actually reduce the computation time. If that is something you think could be an interesting feature, I can open a new issue and start studying the code to see how this could be implemented in a later PR. 

That is what I have in mind.  A second PR for the other feature would also be welcome.

Resolving patch:
diff --git a/statsmodels/tsa/stattools.py b/statsmodels/tsa/stattools.py
--- a/statsmodels/tsa/stattools.py
+++ b/statsmodels/tsa/stattools.py
@@ -1336,18 +1336,17 @@ def grangercausalitytests(x, maxlag, addconst=True, verbose=True):
     addconst = bool_like(addconst, "addconst")
     verbose = bool_like(verbose, "verbose")
     try:
+        maxlag = int_like(maxlag, "maxlag")
+        if maxlag <= 0:
+            raise ValueError("maxlag must a a positive integer")
+        lags = np.arange(1, maxlag + 1)
+    except TypeError:
         lags = np.array([int(lag) for lag in maxlag])
         maxlag = lags.max()
         if lags.min() <= 0 or lags.size == 0:
             raise ValueError(
                 "maxlag must be a non-empty list containing only "
-                "positive integers"
-            )
-    except Exception:
-        maxlag = int_like(maxlag, "maxlag")
-        if maxlag <= 0:
-            raise ValueError("maxlag must a a positive integer")
-        lags = np.arange(1, maxlag + 1)
+                "positive integers")
 
     if x.shape[0] <= 3 * maxlag + int(addconst):
         raise ValueError(


Test patch:
diff --git a/statsmodels/tsa/tests/test_stattools.py b/statsmodels/tsa/tests/test_stattools.py
--- a/statsmodels/tsa/tests/test_stattools.py
+++ b/statsmodels/tsa/tests/test_stattools.py
@@ -481,6 +481,13 @@ def test_granger_fails_on_finite_check(self, reset_randomstate):
         with pytest.raises(ValueError, match="x contains NaN"):
             grangercausalitytests(x, 2)
 
+    def test_granger_fails_on_zero_lag(self, reset_randomstate):
+        x = np.random.rand(1000, 2)
+        with pytest.raises(
+                ValueError,
+                match="maxlag must be a non-empty list containing only positive integers"):
+            grangercausalitytests(x, [0, 1, 2])
+
 
 class TestKPSS:
     """