Repository: statsmodels/statsmodels

Issue:
MAINT: Bump dependencies.
Closes #5839 

(Note: still happy to change these if there are objections / concerns)

Drops support for Python 3.4 and updates dependencies to:

- Numpy >= 1.14 (January 2018)
- Scipy >= 1.0.0 (October 2017)
- Pandas >= 0.21 (October 2017)
- Cython >= 0.27 (September 2017)
- Patsy >= 0.5 (January 2018)

I think I updated all the relevant files, and I bumped some of the versions in Travis that we above the previous minimums to be above these new minimums too. Hope I didn't mess anything up.


Discussion:
Obviously this does not need to be merged quickly. I will tentatively plan to merge it in a week, unless there are concerns.
Out of curiosity, I used this Google Big Query:

```
#standardSQL
SELECT file.filename, COUNT(*) AS num_downloads
FROM `the-psf.pypi.downloads*`
WHERE file.project = 'statsmodels'
  -- Only query the last 30 days of history
  AND _TABLE_SUFFIX
    BETWEEN FORMAT_DATE(
      '%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY))
    AND FORMAT_DATE('%Y%m%d', CURRENT_DATE())
    AND file.version ='0.10.0'
GROUP BY file.filename
ORDER BY file.filename
```

https://bigquery.cloud.google.com/dataset/the-psf:pypi

And it gave me this table... 

https://docs.google.com/spreadsheets/d/1jkBYy12yOTReBywUx2DCu1HRmFj16zoFQoW8BOOZ_lk/edit?usp=sharing

Unless I'm doing something wrong (not unlikely) our #1 platform for downloads is....  cpython 2.7 on 64 bit linux.

Over 30% of wheels are python 2.7 wheels. 



[![Coverage Status](https://coveralls.io/builds/24276261/badge)](https://coveralls.io/builds/24276261)

Coverage decreased (-0.05%) to 85.056% when pulling **25daeac72b026338717239848a03ac2cf4b11984 on ChadFulton:update-deps** into **f907211a0dde0addd2994a7ac5bb3e3f72d77cb7 on statsmodels:master**.

# [Codecov](https://codecov.io/gh/statsmodels/statsmodels/pull/5894?src=pr&el=h1) Report
> Merging [#5894](https://codecov.io/gh/statsmodels/statsmodels/pull/5894?src=pr&el=desc) into [master](https://codecov.io/gh/statsmodels/statsmodels/commit/f907211a0dde0addd2994a7ac5bb3e3f72d77cb7?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/statsmodels/statsmodels/pull/5894/graphs/tree.svg?width=650&token=Og706qJV5S&height=150&src=pr)](https://codecov.io/gh/statsmodels/statsmodels/pull/5894?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master    #5894   +/-   ##
=======================================
  Coverage   82.54%   82.54%           
=======================================
  Files         598      598           
  Lines       94264    94264           
  Branches    10393    10393           
=======================================
  Hits        77810    77810           
- Misses      14045    14046    +1     
+ Partials     2409     2408    -1
```


| [Impacted Files](https://codecov.io/gh/statsmodels/statsmodels/pull/5894?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [statsmodels/stats/descriptivestats.py](https://codecov.io/gh/statsmodels/statsmodels/pull/5894/diff?src=pr&el=tree#diff-c3RhdHNtb2RlbHMvc3RhdHMvZGVzY3JpcHRpdmVzdGF0cy5weQ==) | `24.34% <0%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/statsmodels/statsmodels/pull/5894?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/statsmodels/statsmodels/pull/5894?src=pr&el=footer). Last update [f907211...25daeac](https://codecov.io/gh/statsmodels/statsmodels/pull/5894?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

Most importantly Python should be >=3.5.  It is time for Python 2.7 to end, it has for all other projects I follow. This said, we shouldn't accept refactoring that remove 2.7 code until we are finished backporting to 0.10.1, since it could make backporting harder.  But we can drop it from CI and new code can be 3.5+. 

IMO Cython should be 0.29+.  This is a developer-only tool, and isn't needed to install or run.  IIRC It is also necessary to use Cython 0.29.10 (or later) for Python 3.8 alpha. 
> Over 30% of wheels are python 2.7 wheels.

This must be dominated by CI runs. 
> IMO Cython should be 0.29+. This is a developer-only tool, and isn't needed to install or run. IIRC It is also necessary to use Cython 0.29.10 (or later) for Python 3.8 alpha.

Thanks for pointing this out. I guess we should plan to potentially bump Cython again when Python 3.8 comes out in October (or whenever it finally does) in case of additional changes that require new Cython releases.

In the meantime, what should we do? Bump all the way to 0.29.10? That only came out this month, but I guess it's only an optional dependency.

> Most importantly Python should be >=3.5. It is time for Python 2.7 to end, it has for all other projects I follow. This said, we shouldn't accept refactoring that remove 2.7 code until we are finished backporting to 0.10.1, since it could make backporting harder. But we can drop it from CI and new code can be 3.5+.

This is a good point. I see that @josef-pkt raised the question of dropping support for Python 2.7 in the v0.11 release, and I think (but can't find it now) that we sort-of indicated that v0.10 was going to be the last Python 2.7 compatible release. If this is what we're doing, then I agree it would be best to make the switch now to allowing Python 3.5+ code, and drop Python 2.7 from CI.

Happy to update this PR to do that, but will wait a bit to see if there are other views.
Perhaps keep one 2.7 on Travis for now to make sure that all commits are 2.7 compatible for a little while.  This will help a lot with backports.

For Cython could just do >=0.29, which will result in 0.29.latest in most cases. 

I think MPL needs a bump too.  Perhaps >=2.2 (2.2 is a LTS branch, which is a plus).

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -36,8 +36,8 @@
 ###############################################################################
 # Key Values that Change Each Release
 ###############################################################################
-SETUP_REQUIREMENTS = {'numpy': '1.11',  # released March 2016
-                      'scipy': '0.18',  # released July 2016
+SETUP_REQUIREMENTS = {'numpy': '1.14',  # released January 2018
+                      'scipy': '1.0',  # released October 2017
                       }
 
 REQ_NOT_MET_MSG = """
@@ -59,11 +59,11 @@
         raise RuntimeError(REQ_NOT_MET_MSG.format(key, ver, req_ver))
 
 INSTALL_REQUIREMENTS = SETUP_REQUIREMENTS.copy()
-INSTALL_REQUIREMENTS.update({'pandas': '0.19',  # released October 2016
-                             'patsy': '0.4.0',  # released July 2015
+INSTALL_REQUIREMENTS.update({'pandas': '0.21',  # released October 2017
+                             'patsy': '0.5',  # released January 2018
                              })
 
-CYTHON_MIN_VER = '0.24'  # released Apr 2016
+CYTHON_MIN_VER = '0.29'  # released November 2018
 
 SETUP_REQUIRES = [k + '>=' + v for k, v in SETUP_REQUIREMENTS.items()]
 INSTALL_REQUIRES = [k + '>=' + v for k, v in INSTALL_REQUIREMENTS.items()]
@@ -97,8 +97,6 @@
 CLASSIFIERS = ['Development Status :: 4 - Beta',
                'Environment :: Console',
                'Programming Language :: Cython',
-               'Programming Language :: Python :: 2.7',
-               'Programming Language :: Python :: 3.4',
                'Programming Language :: Python :: 3.5',
                'Programming Language :: Python :: 3.6',
                'Programming Language :: Python :: 3.7',
diff --git a/statsmodels/tsa/holtwinters.py b/statsmodels/tsa/holtwinters.py
--- a/statsmodels/tsa/holtwinters.py
+++ b/statsmodels/tsa/holtwinters.py
@@ -482,8 +482,8 @@ class ExponentialSmoothing(TimeSeriesModel):
 
     def __init__(self, endog, trend=None, damped=False, seasonal=None,
                  seasonal_periods=None, dates=None, freq=None, missing='none'):
-        super(ExponentialSmoothing, self).__init__(
-            endog, None, dates, freq, missing=missing)
+        super(ExponentialSmoothing, self).__init__(endog, None, dates,
+                                                   freq, missing=missing)
         if trend in ['additive', 'multiplicative']:
             trend = {'additive': 'add', 'multiplicative': 'mul'}[trend]
         self.trend = trend
@@ -493,9 +493,10 @@ def __init__(self, endog, trend=None, damped=False, seasonal=None,
         self.seasonal = seasonal
         self.trending = trend in ['mul', 'add']
         self.seasoning = seasonal in ['mul', 'add']
-        if (self.trend == 'mul' or self.seasonal == 'mul') and np.any(endog <= 0.0):
-            raise ValueError('endog must be strictly positive when using multiplicative '
-                             'trend or seasonal components.')
+        if (self.trend == 'mul' or self.seasonal == 'mul') and \
+                np.any(np.asarray(endog) <= 0.0):
+            raise ValueError('endog must be strictly positive when using'
+                             'multiplicative trend or seasonal components.')
         if self.damped and not self.trending:
             raise ValueError('Can only dampen the trend component')
         if self.seasoning:


Test patch: