diff --git a/ci/install_travis.sh b/ci/install_travis.sh index 1b1eae7b44e45..996061ac29af8 100755 --- a/ci/install_travis.sh +++ b/ci/install_travis.sh @@ -130,7 +130,7 @@ else echo "pip installs" REQ="ci/requirements-${TRAVIS_PYTHON_VERSION}${JOB_TAG}.pip" if [ -e ${REQ} ]; then - pip install -r $REQ + pip install --upgrade -r $REQ fi # remove any installed pandas package diff --git a/ci/requirements-2.7.build b/ci/requirements-2.7.build index 6c9965ac0305e..eca8460468d34 100644 --- a/ci/requirements-2.7.build +++ b/ci/requirements-2.7.build @@ -1,4 +1,4 @@ -dateutil=2.1 +python-dateutil=2.4.1 pytz=2013b numpy=1.9.3 cython=0.19.1 diff --git a/ci/requirements-2.7.pip b/ci/requirements-2.7.pip index 54596ad2a8169..9334ca9e03cc1 100644 --- a/ci/requirements-2.7.pip +++ b/ci/requirements-2.7.pip @@ -1,7 +1,7 @@ blosc httplib2 -google-api-python-client == 1.2 -python-gflags == 2.0 -oauth2client == 1.5.0 +google-api-python-client==1.2 +python-gflags==2.0 +oauth2client==1.5.0 pathlib py diff --git a/ci/requirements-2.7.run b/ci/requirements-2.7.run index 6768a75f5c285..0c1132eaa62d3 100644 --- a/ci/requirements-2.7.run +++ b/ci/requirements-2.7.run @@ -1,4 +1,4 @@ -dateutil=2.1 +python-dateutil=2.4.1 pytz=2013b numpy=1.9.3 xlwt=0.7.5 diff --git a/ci/requirements-3.5_OSX.build b/ci/requirements-3.5_OSX.build index 9558cf00ddf5c..8dbecfc9e9292 100644 --- a/ci/requirements-3.5_OSX.build +++ b/ci/requirements-3.5_OSX.build @@ -1,4 +1,2 @@ -python-dateutil -pytz numpy cython diff --git a/ci/requirements-3.5_OSX.pip b/ci/requirements-3.5_OSX.pip new file mode 100644 index 0000000000000..8a7f51f1bea9c --- /dev/null +++ b/ci/requirements-3.5_OSX.pip @@ -0,0 +1 @@ +python-dateutil>=2.5.0 diff --git a/ci/requirements-3.5_OSX.run b/ci/requirements-3.5_OSX.run index 80e12ac3fed34..49c336cae40b1 100644 --- a/ci/requirements-3.5_OSX.run +++ b/ci/requirements-3.5_OSX.run @@ -1,4 +1,3 @@ -python-dateutil pytz numpy openpyxl diff --git a/pandas/compat/__init__.py b/pandas/compat/__init__.py index aade3b8411bb9..24de4985d63f3 100644 --- a/pandas/compat/__init__.py +++ b/pandas/compat/__init__.py @@ -325,6 +325,10 @@ def raise_with_traceback(exc, traceback=Ellipsis): def parse_date(timestr, *args, **kwargs): timestr = bytes(timestr) return _date_parser.parse(timestr, *args, **kwargs) +elif PY2 and LooseVersion(dateutil.__version__) == '2.0': + # dateutil brokenness + raise Exception('dateutil 2.0 incompatible with Python 2.x, you must ' + 'install version 1.5 or 2.1+!') else: parse_date = _date_parser.parse diff --git a/pandas/io/tests/test_parsers.py b/pandas/io/tests/test_parsers.py index f32dfd37e837c..700ec3387d459 100755 --- a/pandas/io/tests/test_parsers.py +++ b/pandas/io/tests/test_parsers.py @@ -10,6 +10,7 @@ import re import nose import platform +from distutils.version import LooseVersion from multiprocessing.pool import ThreadPool @@ -1048,12 +1049,20 @@ def test_parse_dates_string(self): 'C': [2, 4, 5]}, idx) tm.assert_frame_equal(rs, xp) - def test_yy_format(self): + def test_yy_format_with_yearfirst(self): data = """date,time,B,C 090131,0010,1,2 090228,1020,3,4 090331,0830,5,6 """ + + # https://github.com/dateutil/dateutil/issues/217 + import dateutil + if dateutil.__version__ >= LooseVersion('2.5.0'): + raise nose.SkipTest("testing yearfirst=True not-support" + "on datetutil < 2.5.0 this works but" + "is wrong") + rs = self.read_csv(StringIO(data), index_col=0, parse_dates=[['date', 'time']]) idx = DatetimeIndex([datetime(2009, 1, 31, 0, 10, 0), diff --git a/pandas/tseries/tests/test_tslib.py b/pandas/tseries/tests/test_tslib.py index 937a8fa340348..ecbe2827f5447 100644 --- a/pandas/tseries/tests/test_tslib.py +++ b/pandas/tseries/tests/test_tslib.py @@ -474,6 +474,11 @@ def test_does_not_convert_mixed_integer(self): good_date_string)) def test_parsers(self): + + # https://github.com/dateutil/dateutil/issues/217 + import dateutil + yearfirst = dateutil.__version__ >= LooseVersion('2.5.0') + cases = {'2011-01-01': datetime.datetime(2011, 1, 1), '2Q2005': datetime.datetime(2005, 4, 1), '2Q05': datetime.datetime(2005, 4, 1), @@ -527,20 +532,26 @@ def test_parsers(self): } for date_str, expected in compat.iteritems(cases): - result1, _, _ = tools.parse_time_string(date_str) - result2 = to_datetime(date_str) - result3 = to_datetime([date_str]) - result4 = to_datetime(np.array([date_str], dtype=object)) - result5 = Timestamp(date_str) - result6 = DatetimeIndex([date_str])[0] - result7 = date_range(date_str, freq='S', periods=1) + result1, _, _ = tools.parse_time_string(date_str, + yearfirst=yearfirst) + result2 = to_datetime(date_str, yearfirst=yearfirst) + result3 = to_datetime([date_str], yearfirst=yearfirst) + result4 = to_datetime(np.array([date_str], dtype=object), + yearfirst=yearfirst) + result6 = DatetimeIndex([date_str], yearfirst=yearfirst)[0] self.assertEqual(result1, expected) self.assertEqual(result2, expected) self.assertEqual(result3, expected) self.assertEqual(result4, expected) - self.assertEqual(result5, expected) self.assertEqual(result6, expected) - self.assertEqual(result7, expected) + + # these really need to have yearfist, but we don't support + if not yearfirst: + result5 = Timestamp(date_str) + self.assertEqual(result5, expected) + result7 = date_range(date_str, freq='S', periods=1, + yearfirst=yearfirst) + self.assertEqual(result7, expected) # NaT result1, _, _ = tools.parse_time_string('NaT') diff --git a/pandas/tseries/tools.py b/pandas/tseries/tools.py index bbcb68721a0f2..d413a4a2bf096 100644 --- a/pandas/tseries/tools.py +++ b/pandas/tseries/tools.py @@ -1,6 +1,4 @@ from datetime import datetime, timedelta, time -import sys - import numpy as np import pandas.lib as lib @@ -10,17 +8,6 @@ import pandas.compat as compat from pandas.util.decorators import deprecate_kwarg -try: - import dateutil - # raise exception if dateutil 2.0 install on 2.x platform - if (sys.version_info[0] == 2 and - dateutil.__version__ == '2.0'): # pragma: no cover - raise Exception('dateutil 2.0 incompatible with Python 2.x, you must ' - 'install version 1.5 or 2.1+!') -except ImportError: # pragma: no cover - print('Please install python-dateutil via easy_install or some method!') - raise # otherwise a 2nd import won't show the message - _DATEUTIL_LEXER_SPLIT = None try: # Since these are private methods from dateutil, it is safely imported