[Python-checkins] peps: A variety of small edits and clarifications to PEP 495.
guido.van.rossum
python-checkins at python.org
Mon Sep 21 22:21:58 CEST 2015
https://hg.python.org/peps/rev/c9a0cdfd8187
changeset: 6090:c9a0cdfd8187
user: Guido van Rossum <guido at python.org>
date: Mon Sep 21 13:21:26 2015 -0700
summary:
A variety of small edits and clarifications to PEP 495.
files:
pep-0495.txt | 74 ++++++++++++++++++++++++++-------------
1 files changed, 49 insertions(+), 25 deletions(-)
diff --git a/pep-0495.txt b/pep-0495.txt
--- a/pep-0495.txt
+++ b/pep-0495.txt
@@ -41,7 +41,7 @@
.. [#] People who live in locations observing the Daylight Saving
Time (DST) move their clocks back (usually one hour) every Fall.
-
+
It is less common, but occasionally clocks can be moved back for
other reasons. For example, Ukraine skipped the spring-forward
transition in March 1990 and instead, moved their clocks back on
@@ -122,7 +122,11 @@
``fold`` attribute set to that value. In CPython, any non-integer
value of ``fold`` will raise a ``TypeError``, but other
implementations may allow the value ``None`` to behave the same as
-when ``fold`` is not given. [#]_ If the ``fold`` argument is not
+when ``fold`` is not given. [#]_ (This is
+a nod to the existing difference in treatment of ``None`` arguments
+in other positions of this method across Python implementations;
+it is not intended to leave the door open for future alternative
+interpretation of ``fold=None``.) If the ``fold`` argument is not
specified, the original value of the ``fold`` attribute is copied to
the result.
@@ -176,18 +180,23 @@
What time is it?
................
-The ``datetime.now()`` method called with no arguments, will set
+The ``datetime.now()`` method called without arguments will set
``fold=1`` when returning the second of the two ambiguous times in a
system local time fold. When called with a ``tzinfo`` argument, the
value of the ``fold`` will be determined by the ``tzinfo.fromutc()``
-implementation. If an instance of the ``datetime.timezone`` class
-(*e.g.* ``datetime.timezone.utc``) is passed as ``tzinfo``, the
+implementation. When an instance of the ``datetime.timezone`` class
+(the stdlib's fixed-offset ``tzinfo`` subclass,
+*e.g.* ``datetime.timezone.utc``) is passed as ``tzinfo``, the
returned datetime instance will always have ``fold=0``.
+The ``datetime.utcnow()`` method is unaffected.
Conversion from naive to aware
..............................
+A new feature is proposed to facilitate conversion from naive datetime
+instances to aware.
+
The ``astimezone()`` method will now work for naive ``self``. The
system local timezone will be assumed in this case and the ``fold``
flag will be used to determine which local timezone is in effect
@@ -201,6 +210,11 @@
>>> dt.replace(fold=1).astimezone().strftime('%D %T %Z%z')
'11/02/14 01:30:00 EST-0500'
+An implication is that ``datetime.now(tz)`` is fully equivalent to
+``datetime.now().astimezone(tz)`` (assuming ``tz`` is an instance of a
+post-PEP ``tzinfo`` implementation, i.e. one that correctly handles
+and sets ``fold``).
+
Conversion from POSIX seconds from EPOCH
........................................
@@ -229,6 +243,8 @@
datetime.fromtimestamp(s0) == datetime.fromtimestamp(s1) == dt
+(This is because ``==`` disregards the value of fold -- see below.)
+
In this case, ``dt.timestamp()`` will return the smaller of ``s0``
and ``s1`` values if ``dt.fold == 0`` and the larger otherwise.
@@ -240,7 +256,6 @@
>>> datetime(2014, 11, 2, 1, 30, fold=1).timestamp()
1414909800.0
-
When a ``datetime.datetime`` instance ``dt`` represents a missing
time, there is no value ``s`` for which::
@@ -256,6 +271,8 @@
The value returned by ``dt.timestamp()`` given a missing
``dt`` will be the greater of the two "nice to know" values
if ``dt.fold == 0`` and the smaller otherwise.
+(This is not a typo -- it's intentionally backwards from the rule for
+ambiguous times.)
For example, on a system set to US/Eastern timezone::
@@ -272,13 +289,14 @@
changes in the behavior of their aware datetime instances. Two such
instances that differ only by the value of the ``fold`` attribute will
not be distinguishable by any means other than an explicit access to
-the ``fold`` value.
+the ``fold`` value. (This is because these pre-PEP implementations
+are not using the ``fold`` attribute.)
On the other hand, if an object's ``tzinfo`` is set to a fold-aware
-implementation, then the value of ``fold`` will affect the result of
-several methods, but only if the corresponding time is in a fold or in
-a gap: ``utcoffset()``, ``dst()``, ``tzname()``, ``astimezone()``,
-``strftime()`` (if "%Z" or "%z" directive is used in the format
+implementation, then in a fold or gap the value of ``fold`` will
+affect the result of several methods:
+``utcoffset()``, ``dst()``, ``tzname()``, ``astimezone()``,
+``strftime()`` (if the "%Z" or "%z" directive is used in the format
specification), ``isoformat()``, and ``timetuple()``.
@@ -300,8 +318,9 @@
Pickle sizes for the ``datetime.datetime`` and ``datetime.time``
objects will not change. The ``fold`` value will be encoded in the
-first bit of the 3rd (1st) byte of ``datetime.datetime``
-(``datetime.time``) pickle payload. In the `current implementation`_
+first bit of the 3rd byte of the ``datetime.datetime``
+pickle payload; and in the first bit of the 1st byte of the
+``datetime.time`` payload. In the `current implementation`_
these bytes are used to store the month (1-12) and hour (0-23) values
and the first bit is always 0. We picked these bytes because they are
the only bytes that are checked by the current unpickle code. Thus
@@ -324,8 +343,11 @@
``datetime.tzinfo`` class will not change. It is currently not used
anywhere in the stdlib because the only included ``tzinfo``
implementation (the ``datetime.timezone`` class implementing fixed
-offset timezones) override ``fromutc()``.
-
+offset timezones) override ``fromutc()``. Keeping the default
+implementation unchanged has the benefit that pre-PEP 3rd party
+implementations that inherit the default ``fromutc()`` are not
+accidentally affected.
+
Guidelines for New tzinfo Implementations
=========================================
@@ -381,7 +403,7 @@
The ``fromutc()`` method should never produce a time in the gap.
-If ``utcoffset()``, ``tzname()`` or ``dst()`` method is called on a
+If the ``utcoffset()``, ``tzname()`` or ``dst()`` method is called on a
local time that falls in a gap, the rules in effect before the
transition should be used if ``fold=0``. Otherwise, the rules in
effect after the transition should be used.
@@ -477,7 +499,7 @@
by the value of ``fold`` will compare as equal. Applications that
need to differentiate between such instances should check the value of
``fold`` explicitly or convert those instances to a timezone that does
-not have ambiguous times.
+not have ambiguous times (such as UTC).
The value of ``fold`` will also be ignored whenever a timedelta is
added to or subtracted from a datetime instance which may be either
@@ -495,7 +517,9 @@
subtraction.
Naive and intra-zone comparisons will ignore the value of ``fold`` and
-return the same results as they do now.
+return the same results as they do now. (This is the only way to
+preserve backward compatibility. If you need an aware intra-zone
+comparison that uses the fold, convert both sides to UTC first.)
The inter-zone subtraction will be defined as it is now: ``t - s`` is
computed as ``(t - t.utcoffset()) - (s -
@@ -506,14 +530,14 @@
.. [#] Note that the new rules may result in a paradoxical situation
when ``s == t`` but ``s - u != t - u``. Such paradoxes are
not really new and are inherent in the overloading of the minus
- operator as two different intra- and inter-zone operations. For
+ operator differently for intra- and inter-zone operations. For
example, one can easily construct datetime instances ``t`` and ``s``
with some variable offset ``tzinfo`` and a datetime ``u`` with
``tzinfo=timezone.utc`` such that ``(t - u) - (s - u) != t - s``.
The explanation for this paradox is that the minuses inside the
parentheses and the two other minuses are really three different
- operations: inter-zone datetime subtraction, timedelta subtraction
- and intra-zone datetime subtraction which have the mathematical
+ operations: inter-zone datetime subtraction, timedelta subtraction,
+ and intra-zone datetime subtraction, which each have the mathematical
properties of subtraction separately, but not when combined in a
single expression.
@@ -522,9 +546,9 @@
----------------------------------
The aware datetime comparison operators will work the same as they do
-now with results indirectly affected by the value of ``fold`` whenever
-``utcoffset()`` value of one of the operands depends on it, with one
-exception. Whenever one of the operands in inter-zone comparison is
+now, with results indirectly affected by the value of ``fold`` whenever
+the ``utcoffset()`` value of one of the operands depends on it, with one
+exception. Whenever one or both of the operands in inter-zone comparison is
such that its ``utcoffset()`` depends on the value of its ``fold``
fold attribute, the result is ``False``. [#]_
@@ -541,7 +565,7 @@
def toutc(t, fold):
u = t - t.replace(fold=fold).utcoffset()
- return u.replace(tzinfo=None)
+ return u.replace(tzinfo=None)
Then ``t == s`` is equivalent to
--
Repository URL: https://hg.python.org/peps
More information about the Python-checkins
mailing list