-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
bpo-30699: Improve example on tzinfo instances #4290
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
Conversation
vstinner
left a comment
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.
LGTM.
|
Appveyor was stuck. I'll close and re-open the PR to retrigger it. |
|
Thanks, the changes LGTM. If no objection from @abalkin I'll merge it. |
|
Thanks a lot for reviewing this old PRs :) really appreciated |
|
If we are going to update these examples, I think we should make them PEP 495 compliant and I don't think this PR achieves it. |
|
@abalkin not sure I understand what you mean. The examples are moved form UTC naming to GMT, there is no geographical timezone involved and therefore the fold attribute is not relevant. Isn't it? |
|
@mariocj89 - the fold attribute is only irrelevant for a TZ with a never changing offset. As soon as you have DST changes as is the case in these examples, you have to take fold into account when implementing the |
|
@abalkin absolutely right, missed the |
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.
Let's make the examples PEP 495 compliant.
|
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase And if you don't make the requested changes, you will be poked with soft cushions! |
|
@abalkin I trust Mario to come up with something here, but I do think writing a fold-aware example implementation would be way easier if this issue were resolved. I think that would also make I think the fact that it's actually fairly difficult to write a |
|
I am currently quite overwhelmed with work and other organisations, but as soon as I have time i’d Like to get into it and update the examples. I realised when doing it that it is not a 10 minutes job :p TL;DR |
|
@abalkin The code for the timezone classes with support for dst and fold attributes is rather complex. Given the section is to illustrate how to work with datetime and tzinfo objects, what about moving to timezone.utc and a user-defined timezone class based on Kabul? I chose Kabul as it moved its offset once but has no ambiguous times (only imaginary). This still showcases how datetime and tzinfo interact and the code is much simpler! Note there are examples on how to work with tzinfo further down the file. Example implementation: mariocj89@c132630 I can push this to this PR for review if the idea looks good. |
|
@mariocj89 - Using Asia/Kabul for the documentation example sounds fine, but your implementation is incomplete. For the "imaginary" times the result of utcoffset() must depend on the fold value. See Mind the Gap section in PEP 495. |
|
Good point! Always thought that the PEP referred only to DST but indeed apply to all “variable offsets”. Will then update it and push it to this branch. Thanks. |
|
As a note, if something like #7425 (which adds from datetime import datetime, timedelta, tzinfo, timezone
UTC = timezone.utc
class ExampleFold(tzinfo):
def tzname(self, dt):
if self.dst(dt):
return "DST"
else:
return "STD"
def utcoffset(self, dt):
return timedelta(hours=0) + self.dst(dt)
def dst(self, dt):
dt_start = datetime(1, 3, 17, 1).replace(year=dt.year)
dt_end = datetime(1, 11, 4, 1).replace(year=dt.year)
naive_dt = dt.replace(tzinfo=None)
dst_offset = timedelta(hours=1)
if dt_start <= naive_dt < dt_end:
return dst_offset
else:
if naive_dt < dt_end + dt_offset:
if dt.fold:
return timedelta(0)
else:
return dst_offset
return timedelta(0)Obviously that's a sorta weird case because there's no timezone that uses fixed days of the year for offsets, but you can see how easy the "add fold support" part is once |
|
@abalkin I've pushed a potential example implementation. Had to override Also updated the content to pass doctests (only the modified part). Tested that Kabul implementation against the dateutil one before at and after the move. |
|
I removed the " needs backport to 3.6" label, the 3.6 branch no longer accept bugfixes (only security fixes are accepted): https://devguide.python.org/#status-of-python-branches |
pganssle
left a comment
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.
Almost all of my comments here are completely optional and I think this can be merged whether they are incorporated or not.
The only "hard" change that I recommend is the use of "+01:00" instead of "UTC+1" in the TZ1 class.
Doc/library/datetime.rst
Outdated
| datetime.timedelta(0, 14400) | ||
| >>> # Datetime after the change | ||
| >>> dt2 = datetime(2006, 6, 14, 13, 0, tzinfo=tz1) | ||
| >>> dt2.utcoffset() |
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.
Can we change this to:
>>> print(dt.utcoffset())
4:30:00It's a very minor thing, but to me the standard repr for timedelta is completely unreadable.
| ... return timedelta(0) | ||
| ... def tzname(self,dt): | ||
| ... return "GMT +2" | ||
| ... return "+04" |
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.
I would mildly prefer "+04:00" here for consistency, but I don't care strongly about this, it's just a documentation example and I do realize that @abalkin suggested this label.
Doc/library/datetime.rst
Outdated
| ... return timedelta(0) | ||
| ... def tzname(self,dt): | ||
| ... return "Europe/Prague" | ||
| ... return "UTC+1" |
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.
Super annoyingly, POSIX-style offset names have an inverted sense, so dateutil.parser.parse (and I think TZ variables) would interpret UTC+1 as the same as -01:00. Of course, many people use this in the opposite sense, which gives rise to some confusion.
I recommend bypassing the whole thing by returning "+01:00" here.
Move from GMTX to TZX when naming the classes, as GMT1 might be rather confusing as seen in the reported issue. In addition, move to UTC over GMT and improve the tzname implementation.
Move the example in the documentation to just use timezone.utc and a user defined Kabul timezone rather than having two user defined timezones with DST. Kabul timezone is still interesting as it changes its offset but not based on DST. This is more accurate as the previous example was missing information about the fold attribute. Additionally, implementing the fold attribute was rather complex and probably not relevant enough for the section "datetime with tzinfo".
|
@mariocj89 @pganssle |
|
Wow! Totally forgot about this PR 😆 . @abalkin requested to make this PEP 495 complient. There were some suggestions by @pganssle as well but were the opposite of what @abalkin was proposing when formatting offsets. Let me know if there is any change to make! |
|
We can ignore any of my comments that contradict @abalkin's. This is clearly an improvement over the previous state of affairs, and we can always change it later. |
|
@pganssle: You didn't approve this PR. Does it mean that it still lacks someone, or is it good as it is? If yes, can you please officially approve it? |
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.
@vstinner No problem, approved. I think this change is clearly an improvement over the status quo.
I think documentation backports are only going back to 3.7 now anyway, but in case they aren't, this relies on PEP 495, so it can't be backported any further than 3.6. I think it's fine to backport to 3.7 unless @mariocj89 disagrees.
Paul wrote: "We can ignore any of my comments that contradict @abalkin's."
|
Thanks @mariocj89 for the PR, and @vstinner for merging it 🌮🎉.. I'm working now to backport this PR to: 3.7. |
* Improve example on tzinfo instances Move from GMTX to TZX when naming the classes, as GMT1 might be rather confusing as seen in the reported issue. In addition, move to UTC over GMT and improve the tzname implementation. * Simplify datetime with tzinfo example Move the example in the documentation to just use timezone.utc and a user defined Kabul timezone rather than having two user defined timezones with DST. Kabul timezone is still interesting as it changes its offset but not based on DST. This is more accurate as the previous example was missing information about the fold attribute. Additionally, implementing the fold attribute was rather complex and probably not relevant enough for the section "datetime with tzinfo". (cherry picked from commit f0b5ae4) Co-authored-by: Mario Corchero <mcorcherojim@bloomberg.net>
Python 3.6 no longer accept doc changes, only security fixes: https://devguide.python.org/#status-of-python-branches |
|
GH-13811 is a backport of this pull request to the 3.7 branch. |
* Improve example on tzinfo instances Move from GMTX to TZX when naming the classes, as GMT1 might be rather confusing as seen in the reported issue. In addition, move to UTC over GMT and improve the tzname implementation. * Simplify datetime with tzinfo example Move the example in the documentation to just use timezone.utc and a user defined Kabul timezone rather than having two user defined timezones with DST. Kabul timezone is still interesting as it changes its offset but not based on DST. This is more accurate as the previous example was missing information about the fold attribute. Additionally, implementing the fold attribute was rather complex and probably not relevant enough for the section "datetime with tzinfo". (cherry picked from commit f0b5ae4) Co-authored-by: Mario Corchero <mcorcherojim@bloomberg.net>
|
Thanks Mario Corchero for the doc enhancement, and Paul for the review! |
* Improve example on tzinfo instances Move from GMTX to TZX when naming the classes, as GMT1 might be rather confusing as seen in the reported issue. In addition, move to UTC over GMT and improve the tzname implementation. * Simplify datetime with tzinfo example Move the example in the documentation to just use timezone.utc and a user defined Kabul timezone rather than having two user defined timezones with DST. Kabul timezone is still interesting as it changes its offset but not based on DST. This is more accurate as the previous example was missing information about the fold attribute. Additionally, implementing the fold attribute was rather complex and probably not relevant enough for the section "datetime with tzinfo".
Move from GMTX to TZX when naming the classes, as GMT1 might be rather confusing as seen in the reported issue.
In addition, move to UTC over GMT and improve the tzname implementation.
https://bugs.python.org/issue30699