<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Aug 25, 2015 at 9:30 AM, Stuart Bishop <span dir="ltr"><<a href="mailto:stuart@stuartbishop.net" target="_blank">stuart@stuartbishop.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div id=":r7" class="" style="overflow:hidden">As mentioned elsewhere, pytz requires strict checking to remain<br>
backwards compatible.</div></blockquote><div><br></div><div>Can you provide the specific examples where strict checking is required?  Since pytz already has a disambiguation solution, PEP 495 is not as indispensable for it as it is for datetime or dateutil.  However, there is one case I can think of where pytz will benefit: with the PEP, it will be possible to make say Eastern.localize(datetime.now()) work correctly at all times.  If for backward compatibility, you want to continue raising AmbiguousTimeError during one hour each year, I am sure you will figure out how to make Eastern.localize(datetime.now(), isdst=None).  (Hint: Don't change anything in this branch of your code.) </div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div id=":r7" class="" style="overflow:hidden"> The description above does not match the desired<br>
behaviour though.</div></blockquote><div><br></div><div>I assume you refer to "<span style="font-size:12.8000001907349px">Another suggestion was to use first=-1 or first=None to indicate that</span></div><span style="font-size:12.8000001907349px">the program truly has no means to deal with the folds and gaps and</span><br style="font-size:12.8000001907349px"><span style="font-size:12.8000001907349px">dt.utcoffset() should raise an error whenever dt represents an</span><br style="font-size:12.8000001907349px"><span style="font-size:12.8000001907349px">ambiguous or missing local time."</span></div><div class="gmail_quote"><span style="font-size:12.8000001907349px"><br></span></div><div class="gmail_quote"><span style="font-size:12.8000001907349px">It looks like you want to make it impossible to construct invalid dt instances.  In other words, you want to make dt.replace(fold=-1) or dt.replace(tzinfo=Eastern) raise an error under certain circumstances.  Is this right?<br></span><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div id=":r7" class="" style="overflow:hidden"> pytz users need to optionally have exceptions raised<br>
when they try to construct an invalid or ambiguous datetime instance,<br></div></blockquote><div><br></div><div>This is a legitimate need, by why does it need to be done in datetime rather than in pytz itself?  You already ignore the datetime(..., tzinfo=...) constructor and require your users to call localize() instead.  What stops you from providing a function strict_datetime() that will perform any checks that you or your users desire?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div id=":r7" class="" style="overflow:hidden">
directly via __new__ or indirectly with something like  dt.replace().<br></div></blockquote><div><br></div><div>__new__ and .replace() are low level methods called in many performance critical places.  We cannot afford to call arbitrary python code in those methods.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div id=":r7" class="" style="overflow:hidden">
If these methods are called with first=None, it will be passed through<br>
to dt.utcoffset() and it may raise an exception.</div></blockquote><div><br></div><div>This part I don't understand.  If __new__ raises an exception - you will have no instance to "be passed through to dt.utcoffset()."  </div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div id=":r7" class="" style="overflow:hidden"> dt.utcoffset() will<br>
only ever raise an exception when the user has explicitly requested<br>
construction of a datetime with strict checking.</div></blockquote><div><br></div><div>If you allow constructing instances with failing .utcoffset(), these instances will make innocent-looking code capable of raising an error.  For example dt1 in {dt2} will raise the same error as dt2.utcoffset()  regardless of what dt1 is.  You will have similar problems with dt1 == dt2, dictionary lookups, list searches and so on.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div id=":r7" class="" style="overflow:hidden"> It will never raise<br>
an exception in normal operation, including arithmetic, and could not<br>
cause problems in the situations you cite.<br></div></blockquote><div><br></div><div>If I have two instances dt1 and dt2 with different .tzinfo and dt1.utcoffset() raises an exception.  What dt1 - dt2 should return?  or dt1 == dt2?  or hash(dt1)?  </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div id=":r7" class="" style="overflow:hidden">
<br>
This would require the first argument to be available in all the<br>
methods that can construct datetime instances, including things not<br>
mentioned in the PEP like dt.astimezone()</div></blockquote><div><br></div><div>.astimezone() is mentioned in the PEP [1], but I should probably add explicit discussion of how it should handle invalid times.  In my view, the behavior of .astimezone() follows straight from that of .utcoffset(), but it may not be obvious from the PEP alone.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div id=":r7" class="" style="overflow:hidden"> (Where I think it might be<br>
using the first flag from the original dt instance, rather than<br>
allowing the user to specify which side of the fold in the target<br>
zone).</div></blockquote><div><br></div><div> .astimezone() does not and need not "allow the user to specify which side of the fold in the target zone."  As long as it knows how to interpret the time that it is given (disambiguate the fold and "normalize" the gap) it should be able to set the fold=1 attribute correctly in the result if it happen to fall into the repeated hour and should never produce a time that is in the gap of the target zone.</div></div><br>[1]: <a href="https://www.python.org/dev/peps/pep-0495/#conversion-from-naive-to-aware">https://www.python.org/dev/peps/pep-0495/#conversion-from-naive-to-aware</a></div></div>