I think either jumping straight to zoneinfo in 5.0 or using the shim in
4.0 would be fine, though I will say that it is very likely that if you
don't want to change your code twice you won't have to, particularly if
we add a feature flag to opt-in to zoneinfo even in 3.2.

The shim time zones already work the same as `zoneinfo` zones, but they
also expose the pytz interface (with the one semantic difference) and
start raising deprecation warnings. Once your code works with the shims
/without/ throwing deprecation warnings, it will also automatically work
with zoneinfo zones.

In the hopefully conservative time scale I'm envisioning, there would be
a feature flag for 3.2 and 4.x where you can opt in to having Django use
`zoneinfo`, so you don't even need to do anything to get rid of the
shims if you don't want to be passing around shim objects (if you have a
mix of shim and non-shim time zones, datetime comparisons and arithmetic
will have slightly different semantics).

Another thing to note: if you want /any/ kind of warning, you need some
kind of shim, because there are many ways to use pytz time zones that
are not a problem. You need to target the deprecation warnings for code
that actually uses pytz's API, which means wrapping pytz's API. Without
actually supporting zoneinfo, though, users can't actually /do/ anything
with the warning, so they would be forced to change all their time zone
logic at the same time as updating their Django version. My
pytz-deprecation-shim module exposes time zones that don't raise any
warnings if you use them like zoneinfo objects, so people have the
option to gradually move their code into a state where flipping the
switch from pytz to zoneinfo would have very little effect.

Of course, this is all very conservative and assumes that the ability to
gradually migrate is broadly desirable. It may be that Django users by
and large prefer doing major overhauls all at once rather than a
protracted period of gradually upgrading. It also may be that the shims
have some disadvantages I haven't found yet that makes them much worse
than a sudden break. It may also be that y'all would prefer a little
extra pain now to supporting the shim chimera for the lifetime of the
4.x branch.

In my opinion, the strongest argument in favor of a sudden breaking
change in 4.0 would be that the sudden change will be much louder
because stuff will just /break/. With the shims, you'll get a bunch of
Deprecation Warnings (which many people may not see because they are off
by default), and the one backwards-incompatible change is a fairly
subtle difference in arithmetic that only applies in certain situations.
It would be a lot easier to not notice the change until you see a bug
caused by it showing up in production. On the other hand, people not
testing for this adequately may not realize that the semantics are
different than most people think, so they  might have the same bug anyway.

Best,

Paul

On 10/7/20 11:52 AM, Nick Pope wrote:
> Hi Carlton,
>
> Thanks for coming back to this.
>
> Your reasoning makes a lot of sense. I too think it'll be good not to
> land this in 3.2 LTS and focus on making any changes in 4.0.
>
> The question is then which path we choose to take:
>
>  1. The deprecation route using pytz_deprecation_shim in 4.0 changing
>     to zoneinfo in 5.0
>  2. Just make a hard break to zoneinfo in 4.0 replacing
>     the pytz dependency with backports.zoneinfo;python_version<"3.9"
>
> If I'm honest, I actually prefer the second option for the following
> reasons:
>
>   * It avoids having to go through the rigmarole of updating this
>     stuff twice. One release with big shouty warnings is better than two.
>   * People jumping from 3.2 LTS to 4.2 LTS to 5.2 LTS will still have
>     two "consecutive" releases fiddling with this.
>   * When Django 5.0 is released in January 2024, we'll still need to
>     use the backport as Python 3.8 isn't retired until October 2024.
>   * We don't need to introduce, maintain, deprecate, and remove any
>     extra settings for choosing the pytz vs zoneinfo.
>   * As Paul mentioned, most people are probably not using pytz's
>     .normalize() properly anyway...
>
> The disadvantage is that users have to make a major change. But
> they're going to have to sooner or later anyway.
> Using the shim doesn't stop them from having to rewrite their code a
> second time to switch over to zoneinfo.
> With good documentation and examples on how to migrate, I think it
> would be a better approach.
>
> On a final note, I'd like to say thank you to Paul for fixing this
> major timezone handling wart. I'm looking forward to life becoming
> much easier!
>
> Kind regards,
>
> Nick
>
> On Wednesday, 7 October 2020 at 16:26:21 UTC+1 Paul Ganssle wrote:
>
>     This sounds like a reasonable timeline to me. I think the breakage
>     will be relatively small because I suspect many end-users don't
>     really even know to use `normalize` in the first place, and when
>     introducing the shim into a fundamental library at work I did not
>     get a huge number of breakages, but I am still convinced that it
>     is reasonably categorized as a breaking change.
>
>     I do think that there's one additional stage that we need to add
>     here (and we chatted about this on twitter a bit), which is a
>     stage that is fully backwards compatible where Django supports
>     using non-pytz zones for users who bring their own time zone. I
>     suspect that will help ease any breaking pain between 3.2 and 4.0,
>     because no one would be forced to make any changes, but end users
>     could proactively migrate to zoneinfo for a smoother transition.
>
>     I think most of what needs to be done is already in my original
>     PR, it just needs a little conditional logic to handle pytz as
>     well as the shim.
>
>     I am not sure how you feel about feature flags, but as a "nice to
>     have", I imagine it would also be possible to add a feature flag
>     that opts you in to `zoneinfo` as time zone provider even in 3.2,
>     so that people can jump straight to the 5.0 behavior if they are
>     ready for it.
>
>     I should be able to devote some time to at least the first part —
>     making Django compatible with zoneinfo even if not actively using
>     it — but likely not for a few weeks at minimum. If anyone wants to
>     jump on either of these ahead of me I don't mind at all and feel
>     free to ping me for review.
>
>     Best,
>     Paul
>
>     On 10/7/20 10:48 AM, Carlton Gibson wrote:
>>     Hi Paul. 
>>
>>     Thanks for the input here, and for your patience 
>>
>>     > I am fairly certain this is going to be a tricky migration and
>>     will inevitably come with /some/ user pain. I don't think this
>>     will be Python 2 → 3 style pain, but some users who have been
>>     doing the "right thing" with pytz will need to make changes to
>>     their code in the long run, which is unfortunate.
>>
>>     Looking at all the docs, your migration guide on
>>     pytz_deprecation_shim, the example Kevin gave
>>     <https://repl.it/@severian/pytzshim#main.py>, where we do some
>>     arithmetic in a local timezone, and call `normalize()` in case we
>>     crossed a DST boundary, there's no way we can do this without
>>     forcing a breaking change somewhere.
>>
>>     So, probably, I've been staring at this too long today, but I
>>     think we should introduce the shim in Django 4.0. Django 3.2, the
>>     next major release will be an LTS. If we hold-off introducing the
>>     change until 4.0, we can flag it as a breaking change in the 4.0
>>     release notes, with big warnings, allowing folks extra time to
>>     hang out on the previous LTS if they need it. 
>>
>>     What I wouldn't want to do is to bring the breaking change in in
>>     Django 3.2, because we'll have a whole load of folks updating
>>     from the 2.2 LTS at about the time when it goes End of Life, and
>>     with no warning, that'd be a hard breaking change to throw on top
>>     of their other issues. 
>>
>>     We'd keep the shim in place for the entire 4.x series, removing
>>     in Django 5.0 as per the deprecation policy
>>     
>> <https://docs.djangoproject.com/en/3.1/internals/release-process/#deprecation-policy>.
>>
>>     I think the advantages of doing it this way are two-fold: 
>>
>>     * We allow people to focus on the semantic breaking change (in
>>     folds) separately from the code changes per se — the logic may
>>     have changed slightly in these cases, but it'll still run. 
>>     * It looks easier to migrate Django's code vs branching on a new
>>     setting. (I didn't think through exactly what that might look
>>     like, so happy to see a PoC from anyone.)
>>
>>     I'm more attached to the timeline (i.e. making the change after
>>     the next LTS) than whether we use the deprecation shim or not,
>>     but can I ask others to give this their thought too?
>>
>>     Thanks again! 
>>
>>     Kind Regards,
>>
>>     Carlton
>>
>>
>>     -- 
>>     You received this message because you are subscribed to the
>>     Google Groups "Django developers (Contributions to Django
>>     itself)" group.
>>     To unsubscribe from this group and stop receiving emails from it,
>>     send an email to django-develop...@googlegroups.com.
>>     To view this discussion on the web visit
>>     
>> https://groups.google.com/d/msgid/django-developers/ce04a6b7-4409-4b20-ba30-4cd64dc0cabfn%40googlegroups.com
>>     
>> <https://groups.google.com/d/msgid/django-developers/ce04a6b7-4409-4b20-ba30-4cd64dc0cabfn%40googlegroups.com?utm_medium=email&utm_source=footer>.
>
> -- 
> You received this message because you are subscribed to the Google
> Groups "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to django-developers+unsubscr...@googlegroups.com
> <mailto:django-developers+unsubscr...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/be81c1a9-cefa-4f02-a9d6-17e6d1a93c2dn%40googlegroups.com
> <https://groups.google.com/d/msgid/django-developers/be81c1a9-cefa-4f02-a9d6-17e6d1a93c2dn%40googlegroups.com?utm_medium=email&utm_source=footer>.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/a1813e57-6767-e000-a317-06460d377a63%40ganssle.io.

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to