[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