Hello,

As the original author of support for timezone aware datetimes in Django, I've 
been meaning to review this... for six months... Better late than never I guess?

In this discussion, we're assuming settings.USE_TZ = True.


The original design 
<https://groups.google.com/g/django-developers/c/zwQju7hbG78>, which still 
matches 80% of the current implementation, was very much based on advice found 
in the documentation of pytz. This has three consequences:

1. By default, users manipulate aware datetimes in UTC, which limits the 
breakage to cases where they explicitly switch to another timezone. This is 
auditable e.g. "look for timezone.activate or timezone.override in your code".

2. Django provides custom wrappers in order to take care of the pitfalls of 
pytz automatically e.g. timezone.make_aware. Backwards-compatibility can be 
implemented transparently there.

3. A strategy designed for migrating from pytz to zoneinfo should be applicable 
to Django.


I'm seeing three areas that need care:

A. APIs returning a tzinfo object, currently a pytz timezone (other than UTC — 
we switched from Django's custom definition of the UTC tzinfo to pytz' 
definition in the past without trouble).

B. APIs returning aware datetimes, currently in a pytz timezone (other than 
UTC).

C. APIs performing datetime conversions in the database, which is typically 
used for aggregating by day in a given timezone. This depends on the timezone 
name. I think we're fine on this front since we're keeping the same timezone 
names.

So the primary concern is leaking pytz tzinfo objects (either directly, or via 
aware datetime objects), to user code that requested it explicitly. I may sound 
like I'm belaboring the point. However, I think we can make a better 
backwards-compatibility decision with an accurate estimate of the extent of the 
breakage.


Django currently references pytz in the following places:

- timezone.get_default/current_timezone => see case A above.
- timezone.get_default/current_timezone_name => shouldn't be an issue since 
time zone names don't change.
- BaseDatabaseWrapper.timezone => for timezone conversions in Python code via 
make_aware / make_naive; see case B above.
- BaseDatabaseWrapper.timezone_name => for timezone conversions in the database 
via database-specific SQL functions; see case C above.

With SQLite, the SQL conversion functions are implemented in Python and use 
pytz, but the end result is the same.


My suggestion would be:

- Switch everyone to zoneinfo (or backports.zoneinfo) by default in 4.0
- Provide a temporary, immediately deprecated setting USE_PYTZ_DEPRECATION_SHIM 
in 4.0 and remove it in 5.0

Why?

- Most users don't use timezone.activate, timezone.override, or the 
DATABASES.TIME_ZONE setting to get aware datetimes in a timezone other than UTC 
for the purpose of doing datetime arithmetic in local time. Let's keep the 
upgrade instructions simple for the majority of users! "If you don't do 
anything fancy with timezones, you don't need to worry about this!"

- But some users need a more gradual path, especially those with large 
codebases. Conscious use of pytz_deprecation_shim looks like the best plan for 
them. Since it isn't easy to monkey-patch, let's instruct them to set 
USE_PYTZ_DEPRECATION_SHIM = True so they can upgrade now and fix deprecation 
warning later. This would be Paul's pull request 
<https://github.com/django/django/pull/13073>, but conditional on the setting.

I considered using "can we import pytz_deprecation_shim?" as a signal instead 
of "is USE_PYTZ_DEPRECATION_SHIM set?" but this wouldn't work well if 
pytz_deprecation_shim becomes an indirect dependency. Then shims could get 
accidentally activated and the user wouldn't have a good solution.


I hope this helps!

-- 
Aymeric.

-- 
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/1AA84619-74BA-4A7D-A5A8-DC7210885BE9%40polytechnique.org.

Reply via email to