-
-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Checks for tz/tzinfo validity in Timestamp.__new__ #17943
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
7914f55
5c89630
6a2f766
b4c98fb
8f304a6
f812e90
d90bc25
4839ffb
98b5b17
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,6 +30,7 @@ from util cimport (is_integer_object, is_float_object, is_datetime64_object, | |
is_timedelta64_object, INT64_MAX) | ||
cimport util | ||
|
||
from cpython.datetime cimport PyTZInfo_Check | ||
# this is our datetime.pxd | ||
from datetime cimport ( | ||
pandas_datetimestruct, | ||
|
@@ -68,7 +69,7 @@ from .tslibs.parsing import parse_datetime_string | |
|
||
cimport cython | ||
|
||
from pandas.compat import iteritems, callable | ||
from pandas.compat import iteritems | ||
|
||
import collections | ||
import warnings | ||
|
@@ -373,8 +374,24 @@ class Timestamp(_Timestamp): | |
FutureWarning) | ||
freq = offset | ||
|
||
if tzinfo is not None: | ||
if not PyTZInfo_Check(tzinfo): | ||
# tzinfo must be a datetime.tzinfo object, GH#17690 | ||
raise TypeError('tzinfo must be a datetime.tzinfo object, ' | ||
'not %s' % type(tzinfo)) | ||
elif tz is not None: | ||
raise ValueError('Can provide at most one of tz, tzinfo') | ||
elif ts_input is not _no_input: | ||
raise ValueError('When creating a Timestamp with this type ' | ||
'of inputs, the `tzfinfo` argument is ' | ||
'ignored. Use `tz` instead.') | ||
|
||
if ts_input is _no_input: | ||
# User passed keyword arguments. | ||
if tz is not None: | ||
raise ValueError('When creating a Timestamp from component ' | ||
'elements, the `tz` argument is ignored. ' | ||
'Use `tzinfo` instead.') | ||
return Timestamp(datetime(year, month, day, hour or 0, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you should set tzinfo to be None here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK. |
||
minute or 0, second or 0, | ||
microsecond or 0, tzinfo), | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -175,6 +175,21 @@ def test_constructor_invalid(self): | |
with tm.assert_raises_regex(ValueError, 'Cannot convert Period'): | ||
Timestamp(Period('1000-01-01')) | ||
|
||
def test_constructor_invalid_tz(self): | ||
# GH#17690, GH#5168 | ||
with tm.assert_raises_regex(TypeError, 'must be a datetime.tzinfo'): | ||
Timestamp('2017-10-22', tzinfo='US/Eastern') | ||
|
||
with tm.assert_raises_regex(ValueError, 'at most one of'): | ||
Timestamp('2017-10-22', tzinfo=utc, tz='UTC') | ||
|
||
with tm.assert_raises_regex(ValueError, 'Use `tzinfo` instead'): | ||
Timestamp(year=2017, month=10, day=22, tz='UTC') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is also valid, you just can't pass tzinfo thru to the datetime constructor. rather you need to construct the Timestamp, then localize. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK. So the block that currently reads:
should become something like
? |
||
|
||
with tm.assert_raises_regex(ValueError, 'Use `tz` instead'): | ||
dt = datetime(2017, 10, 22) | ||
Timestamp(dt, tzinfo=utc) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is a valid case. you can just do (internally).
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm this gets really verbose since we need to check in a handful of different places. I guess get correctness right first, then circle back for brevity. |
||
|
||
def test_constructor_positional(self): | ||
# see gh-10758 | ||
with pytest.raises(TypeError): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
misspell
what case is this trying to catch? this is a confusing error message
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch on the spell-check, thanks.
Under the status quo, the
tzinfo
kwarg is used in only one branch:In all other cases
tzinfo
is silently ignored. This raises instead of ignoring the input. As you noted below, it may be better to change this behavior.You're right the message is oddly worded. "this type of inputs" in this case is "anything other than the keyword arguments for datetime(...)". Suggestions for wording? (unnecessary if we change the behavior instead)