msg319121 - (view) |
Author: Alexander Belopolsky (belopolsky) *  |
Date: 2018-06-09 00:08 |
Consider the following code: $ cat bug.py import sys if len(sys.argv) > 1: sys.modules['_datetime'] = None from datetime import tzinfo, datetime, timezone class TZ(tzinfo): def utcoffset(self, t): pass print(datetime(2000,1,1,tzinfo=TZ()).astimezone(timezone.utc)) When running with no arguments (with C acceleration), I get $ ./python.exe bug.py 2000-01-01 00:00:00+00:00 but the pure python code produces an error $ ./python.exe bug.py pure Traceback (most recent call last): File "bug.py", line 10, in print(datetime(2000,1,1,tzinfo=TZ()).astimezone(timezone.utc)) File ".../Lib/datetime.py", line 1783, in astimezone raise ValueError("astimezone() requires an aware datetime") ValueError: astimezone() requires an aware datetime Note that some kind of error is expected because TZ.utcoffset() returns None instead of a timedelta, but the error message produced by pure python code is confusing. |
|
|
msg319122 - (view) |
Author: Tim Peters (tim.peters) *  |
Date: 2018-06-09 00:17 |
The message isn't confusing - the definition of "aware" is confusing ;-) """ A datetime object d is aware if d.tzinfo is not None and d.tzinfo.utcoffset(d) does not return None. If d.tzinfo is None, or if d.tzinfo is not None but d.tzinfo.utcoffset(d) returns None, d is naive. """ |
|
|
msg319131 - (view) |
Author: Alexander Belopolsky (belopolsky) *  |
Date: 2018-06-09 03:00 |
So you are suggesting that my datetime(2000,1,1,tzinfo=TZ()) should behave as a naive instance, right? Well, this would be a third behavior different from both current C and Python implementations: >>> print(datetime(2000,1,1).astimezone(timezone.utc)) 2000-01-01 05:00:00+00:00 (I am in US/Eastern timezone.) |
|
|
msg319134 - (view) |
Author: Tim Peters (tim.peters) *  |
Date: 2018-06-09 03:31 |
I copy/pasted the definitions of "aware" and "naive" from the docs. Your TZ's .utcoffset() returns None, so, yes, any datetime using an instance of that for its tzinfo is naive. In print(datetime(2000,1,1).astimezone(timezone.utc)) the docs for astimezone say, in part, """ If self is naive (self.tzinfo is None), it is presumed to represent time in the system timezone. """ So it converted your naive time (viewed as being in your system - EDT - time zone) to UTC. That appears to be using a different definition of "naive" (looking only at whether self.tzinfo is None). The original datetime.py certainly didn't do that ... """ def astimezone(self, tz): if not isinstance(tz, tzinfo): raise TypeError("tz argument must be an instance of tzinfo") mytz = self.tzinfo if mytz is None: raise ValueError("astimezone() requires an aware datetime") if tz is mytz: return self # Convert self to UTC, and attach the new time zone object. myoffset = self.utcoffset() if myoffset is None: raise ValueError("astimezone() requires an aware datetime") """ So it originally used the definition I quoted first. The "sometimes pretend it's local time anyway" twist appeared to get added here: https://github.com/python/cpython/commit/fdc860f3106b59ec908e0b605e51a1607ea2ff4b |
|
|
msg319195 - (view) |
Author: Alexander Belopolsky (belopolsky) *  |
Date: 2018-06-10 03:45 |
Tim, given that I've updated the documentation, should we treat this as a bug fix or a feature? Note that the type check is definitely a bug-fix (if not a security issue), but I clearly had a wrong definition of "naive" in mind when I was modifying astimezone to support naive instances. In any case, it looks like a news entry is in order. |
|
|
msg319196 - (view) |
Author: Tim Peters (tim.peters) *  |
Date: 2018-06-10 03:51 |
I'd call it a bug fix, but I'm really not anal about what people call things ;-) |
|
|
msg319245 - (view) |
Author: Alexander Belopolsky (belopolsky) *  |
Date: 2018-06-10 21:03 |
New changeset 877b23202b7e7d4f57b58504fd0eb886e8c0b377 by Alexander Belopolsky in branch 'master': bpo-33812: Corrected astimezone for naive datetimes. (GH-7578) https://github.com/python/cpython/commit/877b23202b7e7d4f57b58504fd0eb886e8c0b377 |
|
|
msg319253 - (view) |
Author: Alexander Belopolsky (belopolsky) *  |
Date: 2018-06-10 22:02 |
New changeset 037e9125527d4a55af566f161c96a61b3c3fd998 by Alexander Belopolsky (Miss Islington (bot)) in branch '3.7': bpo-33812: Corrected astimezone for naive datetimes. (GH-7578) (GH-7600) https://github.com/python/cpython/commit/037e9125527d4a55af566f161c96a61b3c3fd998 |
|
|
msg319254 - (view) |
Author: Alexander Belopolsky (belopolsky) *  |
Date: 2018-06-10 22:03 |
New changeset 1d4089b5d208ae6f0bd256304fd77f04c0b4fd41 by Alexander Belopolsky (Miss Islington (bot)) in branch '3.6': bpo-33812: Corrected astimezone for naive datetimes. (GH-7578) (GH-7601) https://github.com/python/cpython/commit/1d4089b5d208ae6f0bd256304fd77f04c0b4fd41 |
|
|