Skip to content

Commit 9bf3a28

Browse files
authored
ENH: Timestamp constructor now raises more explanatory error message (#31653)
1 parent 2fc8559 commit 9bf3a28

File tree

3 files changed

+33
-4
lines changed

3 files changed

+33
-4
lines changed

doc/source/whatsnew/v1.1.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ Datetimelike
114114
- :meth:`DatetimeArray.searchsorted`, :meth:`TimedeltaArray.searchsorted`, :meth:`PeriodArray.searchsorted` not recognizing non-pandas scalars and incorrectly raising ``ValueError`` instead of ``TypeError`` (:issue:`30950`)
115115
- Bug in :class:`Timestamp` where constructing :class:`Timestamp` with dateutil timezone less than 128 nanoseconds before daylight saving time switch from winter to summer would result in nonexistent time (:issue:`31043`)
116116
- Bug in :meth:`Period.to_timestamp`, :meth:`Period.start_time` with microsecond frequency returning a timestamp one nanosecond earlier than the correct time (:issue:`31475`)
117+
- :class:`Timestamp` raising confusing error message when year, month or day is missing (:issue:`31200`)
117118

118119
Timedelta
119120
^^^^^^^^^

pandas/_libs/tslibs/timestamps.pyx

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -411,10 +411,25 @@ class Timestamp(_Timestamp):
411411
)
412412

413413
elif ts_input is _no_input:
414-
# User passed keyword arguments.
415-
ts_input = datetime(year, month, day, hour or 0,
416-
minute or 0, second or 0,
417-
microsecond or 0)
414+
# GH 31200
415+
# When year, month or day is not given, we call the datetime
416+
# constructor to make sure we get the same error message
417+
# since Timestamp inherits datetime
418+
datetime_kwargs = {
419+
"hour": hour or 0,
420+
"minute": minute or 0,
421+
"second": second or 0,
422+
"microsecond": microsecond or 0
423+
}
424+
if year is not None:
425+
datetime_kwargs["year"] = year
426+
if month is not None:
427+
datetime_kwargs["month"] = month
428+
if day is not None:
429+
datetime_kwargs["day"] = day
430+
431+
ts_input = datetime(**datetime_kwargs)
432+
418433
elif is_integer_object(freq):
419434
# User passed positional arguments:
420435
# Timestamp(year, month, day[, hour[, minute[, second[,

pandas/tests/scalar/timestamp/test_constructors.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,3 +548,16 @@ def test_timestamp_constructor_identity():
548548
expected = Timestamp("2017-01-01T12")
549549
result = Timestamp(expected)
550550
assert result is expected
551+
552+
553+
@pytest.mark.parametrize("kwargs", [{}, {"year": 2020}, {"year": 2020, "month": 1}])
554+
def test_constructor_missing_keyword(kwargs):
555+
# GH 31200
556+
557+
# The exact error message of datetime() depends on its version
558+
msg1 = r"function missing required argument '(year|month|day)' \(pos [123]\)"
559+
msg2 = r"Required argument '(year|month|day)' \(pos [123]\) not found"
560+
msg = "|".join([msg1, msg2])
561+
562+
with pytest.raises(TypeError, match=msg):
563+
Timestamp(**kwargs)

0 commit comments

Comments
 (0)