Skip to content

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

Merged
merged 9 commits into from
Oct 27, 2017

Conversation

jbrockmendel
Copy link
Member

closes #17690
related #5168

@codecov
Copy link

codecov bot commented Oct 23, 2017

Codecov Report

Merging #17943 into master will decrease coverage by <.01%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff             @@
##           master   #17943      +/-   ##
==========================================
- Coverage   91.24%   91.23%   -0.01%     
==========================================
  Files         163      163              
  Lines       50173    50173              
==========================================
- Hits        45778    45774       -4     
- Misses       4395     4399       +4
Flag Coverage Δ
#multiple 89.04% <ø> (ø) ⬆️
#single 40.29% <ø> (-0.06%) ⬇️
Impacted Files Coverage Δ
pandas/io/gbq.py 25% <0%> (-58.34%) ⬇️
pandas/core/frame.py 97.75% <0%> (-0.1%) ⬇️
pandas/io/msgpack/_version.py 44.65% <0%> (+1.9%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 8137209...98b5b17. Read the comment docs.

Copy link
Contributor

@jreback jreback left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs a whatsnew note.

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 '
Copy link
Contributor

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

Copy link
Member Author

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:

        if ts_input is _no_input:
            # User passed keyword arguments.
            return Timestamp(datetime(year, month, day, hour or 0,
                                      minute or 0, second or 0,
                                      microsecond or 0, tzinfo),
                             tz=tzinfo)

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)


with tm.assert_raises_regex(ValueError, 'Use `tz` instead'):
dt = datetime(2017, 10, 22)
Timestamp(dt, tzinfo=utc)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a valid case. you can just do (internally).

tz, tzinfo = tzinfo, None

Copy link
Member Author

Choose a reason for hiding this comment

The 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.

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')
Copy link
Contributor

Choose a reason for hiding this comment

The 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.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. So the block that currently reads:

        if ts_input is _no_input:
            # User passed keyword arguments.
            return Timestamp(datetime(year, month, day, hour or 0,
                                      minute or 0, second or 0,
                                      microsecond or 0, tzinfo),
                             tz=tzinfo)

should become something like

        if ts_input is _no_input:
            # User passed keyword arguments.
            if tz is None:
                  tz = tzinfo
            return Timestamp(datetime(year, month, day, hour or 0,
                                      minute or 0, second or 0,
                                      microsecond or 0, tzinfo),
                             tz=tz)

?

@jreback jreback added Error Reporting Incorrect or improved errors from pandas Timezones Timezone data dtype labels Oct 23, 2017
if tz is None:
# This allows us to handle the case where the user passes
# `tz` and not `tzinfo`.
tz = tzinfo
return Timestamp(datetime(year, month, day, hour or 0,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should set tzinfo to be None here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK.

@@ -387,6 +400,10 @@ class Timestamp(_Timestamp):
year or 0, month or 0, day or 0,
hour), tz=hour)

if tzinfo is not None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this shouldn't be necessary if you do as the above.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? Changing line 390 above doesn't affect anything at this point in the func.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you have the exact same check above (if tzinfo is not none), so you shoul do this up there. (line 377)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. That requires conditioning on elif not is_integer_object(freq). Just pushed.

@@ -830,6 +830,7 @@ Other API Changes
- Restricted DateOffset keyword arguments. Previously, ``DateOffset`` subclasses allowed arbitrary keyword arguments which could lead to unexpected behavior. Now, only valid arguments will be accepted. (:issue:`17176`).
- Pandas no longer registers matplotlib converters on import. The converters
will be registered and used when the first plot is draw (:issue:`17710`)
- :class:`Timestamp` will no longer silently ignore unused `tz` or `tzinfo` arguments (:issue:`17690`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or invalid tzinfo

@jbrockmendel
Copy link
Member Author

Just pushed fixes for test errors. In a nutshell: the more verbose version is also more robust.

@jbrockmendel
Copy link
Member Author

Travis error in TestClipboard.test_round_trip_valid_encodings looks unrelated.

@@ -830,6 +830,7 @@ Other API Changes
- Restricted DateOffset keyword arguments. Previously, ``DateOffset`` subclasses allowed arbitrary keyword arguments which could lead to unexpected behavior. Now, only valid arguments will be accepted. (:issue:`17176`).
- Pandas no longer registers matplotlib converters on import. The converters
will be registered and used when the first plot is draw (:issue:`17710`)
- :class:`Timestamp` will no longer silently ignore unused or invalid `tz` or `tzinfo` arguments (:issue:`17690`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you move to 0.22.0 same section

@jreback jreback added this to the 0.22.0 milestone Oct 27, 2017
@jreback jreback merged commit f7f33a7 into pandas-dev:master Oct 27, 2017
@jreback
Copy link
Contributor

jreback commented Oct 27, 2017

thanks!

@jbrockmendel jbrockmendel deleted the timestamp-init branch October 27, 2017 22:13
jbrockmendel added a commit to jbrockmendel/pandas that referenced this pull request Oct 30, 2017
jreback pushed a commit that referenced this pull request Oct 31, 2017
peterpanmj pushed a commit to peterpanmj/pandas that referenced this pull request Oct 31, 2017
peterpanmj pushed a commit to peterpanmj/pandas that referenced this pull request Oct 31, 2017
No-Stream pushed a commit to No-Stream/pandas that referenced this pull request Nov 28, 2017
No-Stream pushed a commit to No-Stream/pandas that referenced this pull request Nov 28, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Error Reporting Incorrect or improved errors from pandas Timezones Timezone data dtype
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ERR: Timestamp.__new__ accepts both tz and tzinfo
2 participants