On 27 August 2015 at 08:37, Tim Peters email@example.com wrote:
I don't know whether Stuart mucked with arithmetic because he believed that was necessary in order to get conversions to work correctly (if so, he was mistaken), or whether the effects on arithmetic were just a _consequence_ of using fixed-offset classes all the time (that's "a natural" outcome of using only fixed-offset classes - it would take extra effort to _stop_ it - classic and timeline arithmetic are the same thing in any eternally-fixed-offset timezone) . He said, in an earlier message, that conversion was his primary concern. But maybe we're all using the same words with different meanings.
The fixed-offset classes and sorting arithmetic were the only way to get things round tripping. Take a datetime. Convert it to another timezone. Add one hour to both. Compare. The results were inconsistent. You would only get correct results with fixed offset timezones, because the builtin arithmetic ignored the timezone, because there was no is_dst flag and without it it is impossible to get correct results. The burden was left on tzinfo implementations to deal with the problem. You could have naive times and do arithmetic correctly, or you could have zone aware times and do conversions correctly, but to do both developers had to always convert to and from utc to do the arithmetic. And developers being lazy creatures wouldn't bother because it would normally work, or even always work in their particular timezone, and systems would crash at 4am killing innocent kittens. And this was a problem with my tzinfo implementation, because the only way you could possibly experience the problem was by using my tzinfo implementation. Python had avoided this clearly documented problem by not supplying any tzinfo implementations, even though it would have been easy to create a 'local' one using the information already exposed in the time module, and I'd always assumed that fixing it was a requirement of adding timezone implementations to the standard library. So I fixed it. Drunk on my own cleverness and relative youth, it never occurred to me that it was possible to rationalize the existing behaviour with a straight face, where after going to all the effort of constructing and adding a tzinfo to your datetime it would sit there entirely ignored by Python, except for conversion operations, consistently giving you answers that are demonstrably incorrect using most modern timekeeping systems. I'm still not capable of conjuring up such a monumental rationalization ;)
My hope was that 495 alone would at least spare pytz's users from needing to do a `.normalize()` dance after `.astimezone()` anymore. Although I'm not clear on why it's needed even now.
As far as I know, normalize() is not necessary after astimezone() even now https://answers.launchpad.net/pytz/+question/249229
That agrees with my best guess, but my knowledge of pytz is shallow. If it's correct that the .normalize() dance isn't needed here, it would be nice if Stuart plainly said so on that page, and - of course
- changed the docs to stop saying it _is_ required. And then it's
also the case that I don't see any benefit to pytz from PEP 495 alone. :-(
Yeah, I'm putting off answering that one because I'm not sure if I'll get the answer right. People sometimes think I actually know what I'm doing. I'll have a look after I get the overdue pytz release out.
replace() is just a shortcut for a constructor.
Yet pytz does nothing to check .replace() results, right?
It has no opportunity to check the results at the moment, nor does it have the opportunity to swap in the correct fixed offset tzinfo. It just gets rudely shoved into a datetime instance without consent. So replace gives you what it gives you, and you have to sort it out with a call to normalize, at which point you realize you have a timezone definition from 1910 in play and learn to always construct your localized datetime instances with tzinfo.localize(). Such a lovely user experience.