Skip to content

Commit 33fd5b6

Browse files
committed
add missing return
1 parent 6e1a040 commit 33fd5b6

File tree

9 files changed

+423
-134
lines changed

9 files changed

+423
-134
lines changed

doc/source/user_guide/timedeltas.rst

+2
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,7 @@ Similarly to other of the datetime-like indices, ``DatetimeIndex`` and ``PeriodI
424424
Selections work similarly, with coercion on string-likes and slices:
425425

426426
.. ipython:: python
427+
:okwarning:
427428
428429
s["1 day":"2 day"]
429430
s["1 day 01:00:00"]
@@ -432,6 +433,7 @@ Selections work similarly, with coercion on string-likes and slices:
432433
Furthermore you can use partial string selection and the range will be inferred:
433434

434435
.. ipython:: python
436+
:okwarning:
435437
436438
s["1 day":"1 day 5 hours"]
437439

doc/source/whatsnew/v1.5.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,7 @@ Other Deprecations
770770
- Deprecated the argument ``na_sentinel`` in :func:`factorize`, :meth:`Index.factorize`, and :meth:`.ExtensionArray.factorize`; pass ``use_na_sentinel=True`` instead to use the sentinel ``-1`` for NaN values and ``use_na_sentinel=False`` instead of ``na_sentinel=None`` to encode NaN values (:issue:`46910`)
771771
- Deprecated :meth:`DataFrameGroupBy.transform` not aligning the result when the UDF returned DataFrame (:issue:`45648`)
772772
- Clarified warning from :func:`to_datetime` when delimited dates can't be parsed in accordance to specified ``dayfirst`` argument (:issue:`46210`)
773+
- Emit warning from :func:`to_datetime` when delimited dates can't be parsed in accordance to specified ``dayfirst`` argument even for dates where leading zero is omitted (e.g. ``31/1/2001``) (:issue:`47880`)
773774
- Deprecated :class:`Series` and :class:`Resampler` reducers (e.g. ``min``, ``max``, ``sum``, ``mean``) raising a ``NotImplementedError`` when the dtype is non-numric and ``numeric_only=True`` is provided; this will raise a ``TypeError`` in a future version (:issue:`47500`)
774775
- Deprecated :meth:`Series.rank` returning an empty result when the dtype is non-numeric and ``numeric_only=True`` is provided; this will raise a ``TypeError`` in a future version (:issue:`47500`)
775776
- Deprecated argument ``errors`` for :meth:`Series.mask`, :meth:`Series.where`, :meth:`DataFrame.mask`, and :meth:`DataFrame.where` as ``errors`` had no effect on this methods (:issue:`47728`)

pandas/_libs/tslibs/parsing.pyx

+69-15
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,14 @@ cdef:
9999
int MAX_DAYS_IN_MONTH = 31, MAX_MONTH = 12
100100

101101

102-
cdef inline bint _is_not_delimiter(const char ch):
103-
return strchr(delimiters, ch) == NULL
102+
cdef inline bint _is_delimiter(const char ch):
103+
return strchr(delimiters, ch) != NULL
104+
105+
106+
cdef inline int _parse_1digit(const char* s):
107+
cdef int result = 0
108+
result += getdigit_ascii(s[0], -10) * 1
109+
return result
104110

105111

106112
cdef inline int _parse_2digit(const char* s):
@@ -151,18 +157,37 @@ cdef inline object _parse_delimited_date(str date_string, bint dayfirst):
151157
bint can_swap = 0
152158

153159
buf = get_c_string_buf_and_size(date_string, &length)
154-
if length == 10:
160+
if length == 10 and _is_delimiter(buf[2]) and _is_delimiter(buf[5]):
155161
# parsing MM?DD?YYYY and DD?MM?YYYY dates
156-
if _is_not_delimiter(buf[2]) or _is_not_delimiter(buf[5]):
157-
return None, None
158162
month = _parse_2digit(buf)
159163
day = _parse_2digit(buf + 3)
160164
year = _parse_4digit(buf + 6)
161165
reso = 'day'
162166
can_swap = 1
163-
elif length == 7:
167+
elif length == 9 and _is_delimiter(buf[1]) and _is_delimiter(buf[4]):
168+
# parsing M?DD?YYYY and D?MM?YYYY dates
169+
month = _parse_1digit(buf)
170+
day = _parse_2digit(buf + 2)
171+
year = _parse_4digit(buf + 5)
172+
reso = 'day'
173+
can_swap = 1
174+
elif length == 9 and _is_delimiter(buf[2]) and _is_delimiter(buf[4]):
175+
# parsing MM?D?YYYY and DD?M?YYYY dates
176+
month = _parse_2digit(buf)
177+
day = _parse_1digit(buf + 3)
178+
year = _parse_4digit(buf + 5)
179+
reso = 'day'
180+
can_swap = 1
181+
elif length == 8 and _is_delimiter(buf[1]) and _is_delimiter(buf[3]):
182+
# parsing M?D?YYYY and D?M?YYYY dates
183+
month = _parse_1digit(buf)
184+
day = _parse_1digit(buf + 2)
185+
year = _parse_4digit(buf + 4)
186+
reso = 'day'
187+
can_swap = 1
188+
elif length == 7 and _is_delimiter(buf[2]):
164189
# parsing MM?YYYY dates
165-
if buf[2] == b'.' or _is_not_delimiter(buf[2]):
190+
if buf[2] == b'.':
166191
# we cannot reliably tell whether e.g. 10.2010 is a float
167192
# or a date, thus we refuse to parse it here
168193
return None, None
@@ -238,6 +263,18 @@ cdef inline bint does_string_look_like_time(str parse_string):
238263

239264
return 0 <= hour <= 23 and 0 <= minute <= 59
240265

266+
from pandas.util._exceptions import find_stack_level
267+
268+
269+
def du_parse_with_warning(*args, **kwargs):
270+
parsed = du_parse(*args, **kwargs)
271+
warnings.warn(
272+
"Parsing datetime strings without a format specified, "
273+
"please specify a format to avoid unexpected results",
274+
stacklevel=find_stack_level(),
275+
)
276+
return parsed
277+
241278

242279
def parse_datetime_string(
243280
# NB: This will break with np.str_ (GH#32264) even though
@@ -265,8 +302,12 @@ def parse_datetime_string(
265302

266303
if does_string_look_like_time(date_string):
267304
# use current datetime as default, not pass _DEFAULT_DATETIME
268-
dt = du_parse(date_string, dayfirst=dayfirst,
269-
yearfirst=yearfirst, **kwargs)
305+
dt = du_parse_with_warning(
306+
date_string,
307+
dayfirst=dayfirst,
308+
yearfirst=yearfirst,
309+
**kwargs,
310+
)
270311
return dt
271312

272313
dt, _ = _parse_delimited_date(date_string, dayfirst)
@@ -282,8 +323,13 @@ def parse_datetime_string(
282323
pass
283324

284325
try:
285-
dt = du_parse(date_string, default=_DEFAULT_DATETIME,
286-
dayfirst=dayfirst, yearfirst=yearfirst, **kwargs)
326+
dt = du_parse_with_warning(
327+
date_string,
328+
default=_DEFAULT_DATETIME,
329+
dayfirst=dayfirst,
330+
yearfirst=yearfirst,
331+
**kwargs,
332+
)
287333
except TypeError:
288334
# following may be raised from dateutil
289335
# TypeError: 'NoneType' object is not iterable
@@ -681,7 +727,11 @@ def try_parse_dates(
681727
date = datetime.now()
682728
default = datetime(date.year, date.month, 1)
683729

684-
parse_date = lambda x: du_parse(x, dayfirst=dayfirst, default=default)
730+
parse_date = lambda x: du_parse_with_warning(
731+
x,
732+
dayfirst=dayfirst,
733+
default=default,
734+
)
685735

686736
# EAFP here
687737
try:
@@ -728,13 +778,17 @@ def try_parse_date_and_time(
728778
date = datetime.now()
729779
default = datetime(date.year, date.month, 1)
730780

731-
parse_date = lambda x: du_parse(x, dayfirst=dayfirst, default=default)
781+
parse_date = lambda x: du_parse_with_warning(
782+
x,
783+
dayfirst=dayfirst,
784+
default=default,
785+
)
732786

733787
else:
734788
parse_date = date_parser
735789

736790
if time_parser is None:
737-
parse_time = lambda x: du_parse(x)
791+
parse_time = lambda x: du_parse_with_warning(x)
738792

739793
else:
740794
parse_time = time_parser
@@ -955,7 +1009,7 @@ def guess_datetime_format(dt_str, bint dayfirst=False):
9551009
datetime_attrs_to_format.insert(0, day_attribute_and_format)
9561010

9571011
try:
958-
parsed_datetime = du_parse(dt_str, dayfirst=dayfirst)
1012+
parsed_datetime = du_parse_with_warning(dt_str, dayfirst=dayfirst)
9591013
except (ValueError, OverflowError):
9601014
# In case the datetime can't be parsed, its format cannot be guessed
9611015
return None

pandas/tests/frame/methods/test_reset_index.py

+9-14
Original file line numberDiff line numberDiff line change
@@ -337,24 +337,19 @@ def test_reset_index_multiindex_nan(self):
337337
tm.assert_frame_equal(rs, df)
338338

339339
@pytest.mark.parametrize(
340-
"name",
340+
"name, warn",
341341
[
342-
None,
343-
"foo",
344-
2,
345-
3.0,
346-
pd.Timedelta(6),
347-
Timestamp("2012-12-30", tz="UTC"),
348-
"2012-12-31",
342+
(None, UserWarning),
343+
("foo", UserWarning),
344+
(2, None),
345+
(3.0, None),
346+
(pd.Timedelta(6), None),
347+
(Timestamp("2012-12-30", tz="UTC"), FutureWarning),
348+
("2012-12-31", None),
349349
],
350350
)
351-
def test_reset_index_with_datetimeindex_cols(self, name):
351+
def test_reset_index_with_datetimeindex_cols(self, name, warn):
352352
# GH#5818
353-
warn = None
354-
if isinstance(name, Timestamp) and name.tz is not None:
355-
# _deprecate_mismatched_indexing
356-
warn = FutureWarning
357-
358353
df = DataFrame(
359354
[[1, 2], [3, 4]],
360355
columns=date_range("1/1/2013", "1/2/2013"),

0 commit comments

Comments
 (0)