From 35dd3cf7667699db4162fcbbb1cb45c6eb44d287 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Sat, 30 Jun 2018 16:58:22 -0700 Subject: [PATCH 1/6] make imports more direct, remove unused variable --- pandas/_libs/src/inference.pyx | 3 +-- pandas/_libs/tslibs/conversion.pyx | 2 +- pandas/_libs/tslibs/resolution.pyx | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/pandas/_libs/src/inference.pyx b/pandas/_libs/src/inference.pyx index 1fa07dbed6822..cf887ce1a6387 100644 --- a/pandas/_libs/src/inference.pyx +++ b/pandas/_libs/src/inference.pyx @@ -1225,7 +1225,7 @@ def maybe_convert_objects(ndarray[object] objects, bint try_float=0, ndarray[int64_t] idatetimes ndarray[int64_t] itimedeltas Seen seen = Seen() - object val, onan + object val float64_t fval, fnan n = len(objects) @@ -1244,7 +1244,6 @@ def maybe_convert_objects(ndarray[object] objects, bint try_float=0, timedeltas = np.empty(n, dtype='m8[ns]') itimedeltas = timedeltas.view(np.int64) - onan = np.nan fnan = np.nan for i from 0 <= i < n: diff --git a/pandas/_libs/tslibs/conversion.pyx b/pandas/_libs/tslibs/conversion.pyx index 3cbef82437544..2e1a1e732203e 100644 --- a/pandas/_libs/tslibs/conversion.pyx +++ b/pandas/_libs/tslibs/conversion.pyx @@ -1002,7 +1002,7 @@ cdef inline bisect_right_i8(int64_t *data, int64_t val, Py_ssize_t n): cdef inline str _render_tstamp(int64_t val): """ Helper function to render exception messages""" - from pandas._libs.tslib import Timestamp + from timestamps import Timestamp return str(Timestamp(val)) diff --git a/pandas/_libs/tslibs/resolution.pyx b/pandas/_libs/tslibs/resolution.pyx index 210b201cd08ea..8565857fa945f 100644 --- a/pandas/_libs/tslibs/resolution.pyx +++ b/pandas/_libs/tslibs/resolution.pyx @@ -26,9 +26,9 @@ from conversion import tz_convert from conversion cimport tz_convert_utc_to_tzlocal from ccalendar import MONTH_ALIASES, int_to_weekday from ccalendar cimport get_days_in_month +from timestamps import Timestamp from pandas._libs.properties import cache_readonly -from pandas._libs.tslib import Timestamp from pandas.core.algorithms import unique # TODO: Avoid this non-cython import From 2adbd88fea77058cde9de44e1c25d6ec316a949a Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Sat, 30 Jun 2018 17:04:10 -0700 Subject: [PATCH 2/6] change py-space import to cy-space definition --- pandas/_libs/tslibs/period.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/_libs/tslibs/period.pyx b/pandas/_libs/tslibs/period.pyx index 6985d3b8df363..0eaa3ead5cff6 100644 --- a/pandas/_libs/tslibs/period.pyx +++ b/pandas/_libs/tslibs/period.pyx @@ -15,8 +15,6 @@ from libc.stdlib cimport free, malloc from libc.time cimport strftime, tm from libc.string cimport strlen, memset -from pandas.compat import PY2 - cimport cython from cpython.datetime cimport (PyDateTime_Check, PyDelta_Check, @@ -59,6 +57,8 @@ from nattype cimport _nat_scalar_rules, NPY_NAT from pandas.tseries import offsets from pandas.tseries import frequencies +cdef bint PY2 = str == bytes + cdef extern from "period_helper.h": int FR_ANN From 18c1378c59649a661609cb89050773b4bcbd4ff5 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Sat, 30 Jun 2018 17:19:56 -0700 Subject: [PATCH 3/6] implement test_tslib, move test_normalize_date from test_tools --- pandas/tests/indexes/datetimes/test_tools.py | 12 ------------ pandas/tests/tslibs/test_tslib.py | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 12 deletions(-) create mode 100644 pandas/tests/tslibs/test_tslib.py diff --git a/pandas/tests/indexes/datetimes/test_tools.py b/pandas/tests/indexes/datetimes/test_tools.py index e09c1b3f19d1a..b94aa9e5b3b31 100644 --- a/pandas/tests/indexes/datetimes/test_tools.py +++ b/pandas/tests/indexes/datetimes/test_tools.py @@ -1516,18 +1516,6 @@ def test_parsers_timezone_minute_offsets_roundtrip(self, cache): assert dt_string_repr == repr(converted_time) -def test_normalize_date(): - value = date(2012, 9, 7) - - result = tslib.normalize_date(value) - assert (result == datetime(2012, 9, 7)) - - value = datetime(2012, 9, 7, 12) - - result = tslib.normalize_date(value) - assert (result == datetime(2012, 9, 7)) - - @pytest.fixture(params=['D', 's', 'ms', 'us', 'ns']) def units(request): return request.param diff --git a/pandas/tests/tslibs/test_tslib.py b/pandas/tests/tslibs/test_tslib.py new file mode 100644 index 0000000000000..61e81122c3480 --- /dev/null +++ b/pandas/tests/tslibs/test_tslib.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +"""Tests for functions from pandas._libs.tslibs""" + +from datetime import datetime, datetime + +from pandas._libs import tslib + + +def test_normalize_date(): + value = date(2012, 9, 7) + + result = tslib.normalize_date(value) + assert (result == datetime(2012, 9, 7)) + + value = datetime(2012, 9, 7, 12) + + result = tslib.normalize_date(value) + assert (result == datetime(2012, 9, 7)) From 050d9845d8aa49002d948bf921d8ebb24ac28f2f Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Sat, 30 Jun 2018 17:32:51 -0700 Subject: [PATCH 4/6] parametrize test --- pandas/tests/indexes/datetimes/test_tools.py | 160 +++++++++---------- 1 file changed, 80 insertions(+), 80 deletions(-) diff --git a/pandas/tests/indexes/datetimes/test_tools.py b/pandas/tests/indexes/datetimes/test_tools.py index b94aa9e5b3b31..227d6596ce264 100644 --- a/pandas/tests/indexes/datetimes/test_tools.py +++ b/pandas/tests/indexes/datetimes/test_tools.py @@ -1251,92 +1251,92 @@ def test_day_not_in_month_ignore(self, cache): class TestDatetimeParsingWrappers(object): + @pytest.mark.parametrize('date_str,expected', list({ + '2011-01-01': datetime(2011, 1, 1), + '2Q2005': datetime(2005, 4, 1), + '2Q05': datetime(2005, 4, 1), + '2005Q1': datetime(2005, 1, 1), + '05Q1': datetime(2005, 1, 1), + '2011Q3': datetime(2011, 7, 1), + '11Q3': datetime(2011, 7, 1), + '3Q2011': datetime(2011, 7, 1), + '3Q11': datetime(2011, 7, 1), + + # quarterly without space + '2000Q4': datetime(2000, 10, 1), + '00Q4': datetime(2000, 10, 1), + '4Q2000': datetime(2000, 10, 1), + '4Q00': datetime(2000, 10, 1), + '2000q4': datetime(2000, 10, 1), + '2000-Q4': datetime(2000, 10, 1), + '00-Q4': datetime(2000, 10, 1), + '4Q-2000': datetime(2000, 10, 1), + '4Q-00': datetime(2000, 10, 1), + '00q4': datetime(2000, 10, 1), + '2005': datetime(2005, 1, 1), + '2005-11': datetime(2005, 11, 1), + '2005 11': datetime(2005, 11, 1), + '11-2005': datetime(2005, 11, 1), + '11 2005': datetime(2005, 11, 1), + '200511': datetime(2020, 5, 11), + '20051109': datetime(2005, 11, 9), + '20051109 10:15': datetime(2005, 11, 9, 10, 15), + '20051109 08H': datetime(2005, 11, 9, 8, 0), + '2005-11-09 10:15': datetime(2005, 11, 9, 10, 15), + '2005-11-09 08H': datetime(2005, 11, 9, 8, 0), + '2005/11/09 10:15': datetime(2005, 11, 9, 10, 15), + '2005/11/09 08H': datetime(2005, 11, 9, 8, 0), + "Thu Sep 25 10:36:28 2003": datetime(2003, 9, 25, 10, + 36, 28), + "Thu Sep 25 2003": datetime(2003, 9, 25), + "Sep 25 2003": datetime(2003, 9, 25), + "January 1 2014": datetime(2014, 1, 1), + + # GHE10537 + '2014-06': datetime(2014, 6, 1), + '06-2014': datetime(2014, 6, 1), + '2014-6': datetime(2014, 6, 1), + '6-2014': datetime(2014, 6, 1), + + '20010101 12': datetime(2001, 1, 1, 12), + '20010101 1234': datetime(2001, 1, 1, 12, 34), + '20010101 123456': datetime(2001, 1, 1, 12, 34, 56), + }.items())) @pytest.mark.parametrize('cache', [True, False]) - def test_parsers(self, cache): + def test_parsers(self, date_str, expected, cache): # dateutil >= 2.5.0 defaults to yearfirst=True # https://github.com/dateutil/dateutil/issues/217 yearfirst = True - cases = {'2011-01-01': datetime(2011, 1, 1), - '2Q2005': datetime(2005, 4, 1), - '2Q05': datetime(2005, 4, 1), - '2005Q1': datetime(2005, 1, 1), - '05Q1': datetime(2005, 1, 1), - '2011Q3': datetime(2011, 7, 1), - '11Q3': datetime(2011, 7, 1), - '3Q2011': datetime(2011, 7, 1), - '3Q11': datetime(2011, 7, 1), - - # quarterly without space - '2000Q4': datetime(2000, 10, 1), - '00Q4': datetime(2000, 10, 1), - '4Q2000': datetime(2000, 10, 1), - '4Q00': datetime(2000, 10, 1), - '2000q4': datetime(2000, 10, 1), - '2000-Q4': datetime(2000, 10, 1), - '00-Q4': datetime(2000, 10, 1), - '4Q-2000': datetime(2000, 10, 1), - '4Q-00': datetime(2000, 10, 1), - '00q4': datetime(2000, 10, 1), - '2005': datetime(2005, 1, 1), - '2005-11': datetime(2005, 11, 1), - '2005 11': datetime(2005, 11, 1), - '11-2005': datetime(2005, 11, 1), - '11 2005': datetime(2005, 11, 1), - '200511': datetime(2020, 5, 11), - '20051109': datetime(2005, 11, 9), - '20051109 10:15': datetime(2005, 11, 9, 10, 15), - '20051109 08H': datetime(2005, 11, 9, 8, 0), - '2005-11-09 10:15': datetime(2005, 11, 9, 10, 15), - '2005-11-09 08H': datetime(2005, 11, 9, 8, 0), - '2005/11/09 10:15': datetime(2005, 11, 9, 10, 15), - '2005/11/09 08H': datetime(2005, 11, 9, 8, 0), - "Thu Sep 25 10:36:28 2003": datetime(2003, 9, 25, 10, - 36, 28), - "Thu Sep 25 2003": datetime(2003, 9, 25), - "Sep 25 2003": datetime(2003, 9, 25), - "January 1 2014": datetime(2014, 1, 1), - - # GH 10537 - '2014-06': datetime(2014, 6, 1), - '06-2014': datetime(2014, 6, 1), - '2014-6': datetime(2014, 6, 1), - '6-2014': datetime(2014, 6, 1), - - '20010101 12': datetime(2001, 1, 1, 12), - '20010101 1234': datetime(2001, 1, 1, 12, 34), - '20010101 123456': datetime(2001, 1, 1, 12, 34, 56), - } - - for date_str, expected in compat.iteritems(cases): - result1, _, _ = parsing.parse_time_string(date_str, - yearfirst=yearfirst) - result2 = to_datetime(date_str, yearfirst=yearfirst) - result3 = to_datetime([date_str], yearfirst=yearfirst) - # result5 is used below - result4 = to_datetime(np.array([date_str], dtype=object), - yearfirst=yearfirst, cache=cache) - result6 = DatetimeIndex([date_str], yearfirst=yearfirst) - # result7 is used below - result8 = DatetimeIndex(Index([date_str]), yearfirst=yearfirst) - result9 = DatetimeIndex(Series([date_str]), yearfirst=yearfirst) - - for res in [result1, result2]: - assert res == expected - for res in [result3, result4, result6, result8, result9]: - exp = DatetimeIndex([pd.Timestamp(expected)]) - tm.assert_index_equal(res, exp) - - # these really need to have yearfirst, but we don't support - if not yearfirst: - result5 = Timestamp(date_str) - assert result5 == expected - result7 = date_range(date_str, freq='S', periods=1, - yearfirst=yearfirst) - assert result7 == expected - - # NaT + result1, _, _ = parsing.parse_time_string(date_str, + yearfirst=yearfirst) + result2 = to_datetime(date_str, yearfirst=yearfirst) + result3 = to_datetime([date_str], yearfirst=yearfirst) + # result5 is used below + result4 = to_datetime(np.array([date_str], dtype=object), + yearfirst=yearfirst, cache=cache) + result6 = DatetimeIndex([date_str], yearfirst=yearfirst) + # result7 is used below + result8 = DatetimeIndex(Index([date_str]), yearfirst=yearfirst) + result9 = DatetimeIndex(Series([date_str]), yearfirst=yearfirst) + + for res in [result1, result2]: + assert res == expected + for res in [result3, result4, result6, result8, result9]: + exp = DatetimeIndex([pd.Timestamp(expected)]) + tm.assert_index_equal(res, exp) + + # these really need to have yearfirst, but we don't support + if not yearfirst: + result5 = Timestamp(date_str) + assert result5 == expected + result7 = date_range(date_str, freq='S', periods=1, + yearfirst=yearfirst) + assert result7 == expected + + def test_parsers_nat(self): + # Test that each of several string-accepting methods return pd.NaT result1, _, _ = parsing.parse_time_string('NaT') result2 = to_datetime('NaT') result3 = Timestamp('NaT') From b4c0307dd4882764b1d6f6ef894c6c9c153bd5fa Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Sat, 30 Jun 2018 18:04:50 -0700 Subject: [PATCH 5/6] flake8 cleanups --- pandas/tests/indexes/datetimes/test_tools.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/pandas/tests/indexes/datetimes/test_tools.py b/pandas/tests/indexes/datetimes/test_tools.py index 227d6596ce264..fa9f9fc90387a 100644 --- a/pandas/tests/indexes/datetimes/test_tools.py +++ b/pandas/tests/indexes/datetimes/test_tools.py @@ -7,7 +7,7 @@ import dateutil import numpy as np from dateutil.parser import parse -from datetime import datetime, date, time +from datetime import datetime, time from distutils.version import LooseVersion import pandas as pd @@ -1286,8 +1286,7 @@ class TestDatetimeParsingWrappers(object): '2005-11-09 08H': datetime(2005, 11, 9, 8, 0), '2005/11/09 10:15': datetime(2005, 11, 9, 10, 15), '2005/11/09 08H': datetime(2005, 11, 9, 8, 0), - "Thu Sep 25 10:36:28 2003": datetime(2003, 9, 25, 10, - 36, 28), + "Thu Sep 25 10:36:28 2003": datetime(2003, 9, 25, 10, 36, 28), "Thu Sep 25 2003": datetime(2003, 9, 25), "Sep 25 2003": datetime(2003, 9, 25), "January 1 2014": datetime(2014, 1, 1), @@ -1300,8 +1299,7 @@ class TestDatetimeParsingWrappers(object): '20010101 12': datetime(2001, 1, 1, 12), '20010101 1234': datetime(2001, 1, 1, 12, 34), - '20010101 123456': datetime(2001, 1, 1, 12, 34, 56), - }.items())) + '20010101 123456': datetime(2001, 1, 1, 12, 34, 56)}.items())) @pytest.mark.parametrize('cache', [True, False]) def test_parsers(self, date_str, expected, cache): From 2e4a2cdb6313d1afb453bc420ff87071bbab35bc Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Sat, 30 Jun 2018 19:49:19 -0700 Subject: [PATCH 6/6] fixup import typo --- pandas/tests/tslibs/test_tslib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/tslibs/test_tslib.py b/pandas/tests/tslibs/test_tslib.py index 61e81122c3480..2641c016e8674 100644 --- a/pandas/tests/tslibs/test_tslib.py +++ b/pandas/tests/tslibs/test_tslib.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """Tests for functions from pandas._libs.tslibs""" -from datetime import datetime, datetime +from datetime import datetime, date from pandas._libs import tslib