Skip to content

Commit 0843911

Browse files
committed
TST: fix up python-dateutil compat for 2.5.3
closes #12944 closes #12951
1 parent f23f329 commit 0843911

File tree

7 files changed

+101
-82
lines changed

7 files changed

+101
-82
lines changed

doc/source/timeseries.rst

+4-4
Original file line numberDiff line numberDiff line change
@@ -199,10 +199,10 @@ You can also pass a ``DataFrame`` of integer or string columns to assemble into
199199

200200
.. ipython:: python
201201
202-
df = pd.pd.DataFrame({'year': [2015, 2016],
203-
'month': [2, 3],
204-
'day': [4, 5],
205-
'hour': [2, 3]})
202+
df = pd.DataFrame({'year': [2015, 2016],
203+
'month': [2, 3],
204+
'day': [4, 5],
205+
'hour': [2, 3]})
206206
pd.to_datetime(df)
207207
208208

doc/source/whatsnew/v0.18.1.txt

-2
Original file line numberDiff line numberDiff line change
@@ -170,11 +170,9 @@ Other Enhancements
170170

171171

172172
- ``pd.crosstab()`` has gained a ``normalize`` argument for normalizing frequency tables (:issue:`12569`). Examples in the updated docs :ref:`here <reshaping.crosstabulations>`.
173-
174173
- ``.resample(..).interpolate()`` is now supported (:issue:`12925`)
175174

176175

177-
178176
.. _whatsnew_0181.sparse:
179177

180178
Sparse changes

pandas/src/inference.pyx

+2-2
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ def maybe_convert_objects(ndarray[object] objects, bint try_float=0,
683683
seen_float = 1
684684
elif util.is_datetime64_object(val):
685685
if convert_datetime:
686-
idatetimes[i] = convert_to_tsobject(val, None, None).value
686+
idatetimes[i] = convert_to_tsobject(val, None, None, 0, 0).value
687687
seen_datetime = 1
688688
else:
689689
seen_object = 1
@@ -712,7 +712,7 @@ def maybe_convert_objects(ndarray[object] objects, bint try_float=0,
712712
elif PyDateTime_Check(val) or util.is_datetime64_object(val):
713713
if convert_datetime:
714714
seen_datetime = 1
715-
idatetimes[i] = convert_to_tsobject(val, None, None).value
715+
idatetimes[i] = convert_to_tsobject(val, None, None, 0, 0).value
716716
else:
717717
seen_object = 1
718718
break

pandas/tseries/tests/test_tslib.py

+71-48
Original file line numberDiff line numberDiff line change
@@ -592,78 +592,101 @@ def test_parsers_quarter_invalid(self):
592592
self.assertRaises(ValueError, tools.parse_time_string, case)
593593

594594
def test_parsers_dayfirst_yearfirst(self):
595+
tm._skip_if_no_dateutil()
596+
597+
# OK
598+
# 2.5.1 10-11-12 [dayfirst=0, yearfirst=0] -> 2012-10-11 00:00:00
599+
# 2.5.2 10-11-12 [dayfirst=0, yearfirst=1] -> 2012-10-11 00:00:00
600+
# 2.5.3 10-11-12 [dayfirst=0, yearfirst=0] -> 2012-10-11 00:00:00
601+
602+
# OK
603+
# 2.5.1 10-11-12 [dayfirst=0, yearfirst=1] -> 2010-11-12 00:00:00
604+
# 2.5.2 10-11-12 [dayfirst=0, yearfirst=1] -> 2010-11-12 00:00:00
605+
# 2.5.3 10-11-12 [dayfirst=0, yearfirst=1] -> 2010-11-12 00:00:00
606+
607+
# bug fix in 2.5.2
608+
# 2.5.1 10-11-12 [dayfirst=1, yearfirst=1] -> 2010-11-12 00:00:00
609+
# 2.5.2 10-11-12 [dayfirst=1, yearfirst=1] -> 2010-12-11 00:00:00
610+
# 2.5.3 10-11-12 [dayfirst=1, yearfirst=1] -> 2010-12-11 00:00:00
611+
612+
# OK
613+
# 2.5.1 10-11-12 [dayfirst=1, yearfirst=0] -> 2012-11-10 00:00:00
614+
# 2.5.2 10-11-12 [dayfirst=1, yearfirst=0] -> 2012-11-10 00:00:00
615+
# 2.5.3 10-11-12 [dayfirst=1, yearfirst=0] -> 2012-11-10 00:00:00
616+
617+
# OK
618+
# 2.5.1 20/12/21 [dayfirst=0, yearfirst=0] -> 2021-12-20 00:00:00
619+
# 2.5.2 20/12/21 [dayfirst=0, yearfirst=0] -> 2021-12-20 00:00:00
620+
# 2.5.3 20/12/21 [dayfirst=0, yearfirst=0] -> 2021-12-20 00:00:00
621+
622+
# OK
623+
# 2.5.1 20/12/21 [dayfirst=0, yearfirst=1] -> 2020-12-21 00:00:00
624+
# 2.5.2 20/12/21 [dayfirst=0, yearfirst=1] -> 2020-12-21 00:00:00
625+
# 2.5.3 20/12/21 [dayfirst=0, yearfirst=1] -> 2020-12-21 00:00:00
626+
627+
# revert of bug in 2.5.2
628+
# 2.5.1 20/12/21 [dayfirst=1, yearfirst=1] -> 2020-12-21 00:00:00
629+
# 2.5.2 20/12/21 [dayfirst=1, yearfirst=1] -> month must be in 1..12
630+
# 2.5.3 20/12/21 [dayfirst=1, yearfirst=1] -> 2020-12-21 00:00:00
631+
632+
# OK
633+
# 2.5.1 20/12/21 [dayfirst=1, yearfirst=0] -> 2021-12-20 00:00:00
634+
# 2.5.2 20/12/21 [dayfirst=1, yearfirst=0] -> 2021-12-20 00:00:00
635+
# 2.5.3 20/12/21 [dayfirst=1, yearfirst=0] -> 2021-12-20 00:00:00
595636

596-
# https://github.com/dateutil/dateutil/issues/217
597-
# this issue was closed
598637
import dateutil
599-
is_compat_version = dateutil.__version__ >= LooseVersion('2.5.2')
600-
if is_compat_version:
601-
dayfirst_yearfirst1 = datetime.datetime(2010, 12, 11)
602-
dayfirst_yearfirst2 = datetime.datetime(2020, 12, 21)
603-
else:
604-
dayfirst_yearfirst1 = datetime.datetime(2010, 11, 12)
605-
dayfirst_yearfirst2 = datetime.datetime(2020, 12, 21)
638+
is_lt_253 = dateutil.__version__ < LooseVersion('2.5.3')
606639

607640
# str : dayfirst, yearfirst, expected
608-
cases = {'10-11-12': [(False, False, False,
641+
cases = {'10-11-12': [(False, False,
609642
datetime.datetime(2012, 10, 11)),
610-
(True, False, False,
643+
(True, False,
611644
datetime.datetime(2012, 11, 10)),
612-
(False, True, False,
645+
(False, True,
613646
datetime.datetime(2010, 11, 12)),
614-
(True, True, False, dayfirst_yearfirst1)],
615-
'20/12/21': [(False, False, False,
647+
(True, True,
648+
datetime.datetime(2010, 12, 11))],
649+
'20/12/21': [(False, False,
616650
datetime.datetime(2021, 12, 20)),
617-
(True, False, False,
651+
(True, False,
618652
datetime.datetime(2021, 12, 20)),
619-
(False, True, False,
653+
(False, True,
620654
datetime.datetime(2020, 12, 21)),
621-
(True, True, True, dayfirst_yearfirst2)]}
655+
(True, True,
656+
datetime.datetime(2020, 12, 21))]}
622657

623-
tm._skip_if_no_dateutil()
624658
from dateutil.parser import parse
625659
for date_str, values in compat.iteritems(cases):
626-
for dayfirst, yearfirst, is_compat, expected in values:
660+
for dayfirst, yearfirst, expected in values:
627661

628-
f = lambda x: tools.parse_time_string(x,
629-
dayfirst=dayfirst,
630-
yearfirst=yearfirst)
631-
632-
# we now have an invalid parse
633-
if is_compat and is_compat_version:
634-
self.assertRaises(tslib.DateParseError, f, date_str)
635-
636-
def f(date_str):
637-
return to_datetime(date_str, dayfirst=dayfirst,
638-
yearfirst=yearfirst)
639-
640-
self.assertRaises(ValueError, f, date_str)
641-
642-
def f(date_str):
643-
return DatetimeIndex([date_str], dayfirst=dayfirst,
644-
yearfirst=yearfirst)[0]
662+
# odd comparisons across version
663+
# let's just skip
664+
if dayfirst and yearfirst and is_lt_253:
665+
continue
645666

646-
self.assertRaises(ValueError, f, date_str)
667+
# compare with dateutil result
668+
dateutil_result = parse(date_str, dayfirst=dayfirst,
669+
yearfirst=yearfirst)
670+
self.assertEqual(dateutil_result, expected)
647671

648-
continue
672+
result1, _, _ = tools.parse_time_string(date_str,
673+
dayfirst=dayfirst,
674+
yearfirst=yearfirst)
649675

650-
result1, _, _ = f(date_str)
676+
# we don't support dayfirst/yearfirst here:
677+
if not dayfirst and not yearfirst:
678+
result2 = Timestamp(date_str)
679+
self.assertEqual(result2, expected)
651680

652-
result2 = to_datetime(date_str, dayfirst=dayfirst,
681+
result3 = to_datetime(date_str, dayfirst=dayfirst,
653682
yearfirst=yearfirst)
654683

655-
result3 = DatetimeIndex([date_str], dayfirst=dayfirst,
684+
result4 = DatetimeIndex([date_str], dayfirst=dayfirst,
656685
yearfirst=yearfirst)[0]
657686

658-
# Timestamp doesn't support dayfirst and yearfirst
659687
self.assertEqual(result1, expected)
660-
self.assertEqual(result2, expected)
661688
self.assertEqual(result3, expected)
662-
663-
# compare with dateutil result
664-
dateutil_result = parse(date_str, dayfirst=dayfirst,
665-
yearfirst=yearfirst)
666-
self.assertEqual(dateutil_result, expected)
689+
self.assertEqual(result4, expected)
667690

668691
def test_parsers_timestring(self):
669692
tm._skip_if_no_dateutil()

pandas/tseries/tools.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -470,8 +470,8 @@ def f(value):
470470
required = ['year', 'month', 'day']
471471
req = sorted(list(set(required) - set(unit_rev.keys())))
472472
if len(req):
473-
raise ValueError("to assemble mappings with a dict of "
474-
"units, requires year, month, day: "
473+
raise ValueError("to assemble mappings requires at "
474+
"least that [year, month, day] be specified: "
475475
"[{0}] is missing".format(','.join(req)))
476476

477477
# keys we don't recognize

pandas/tslib.pxd

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from numpy cimport ndarray, int64_t
22

3-
cdef convert_to_tsobject(object, object, object)
3+
cdef convert_to_tsobject(object, object, object, bint, bint)
44
cdef convert_to_timedelta64(object, object, object)
55
cpdef object maybe_get_tz(object)
66
cdef bint _is_utc(object)

0 commit comments

Comments
 (0)