Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python 3.13 deprecation of utcnow() #473

Open
jenstroeger opened this issue Dec 9, 2024 · 9 comments
Open

Python 3.13 deprecation of utcnow() #473

jenstroeger opened this issue Dec 9, 2024 · 9 comments

Comments

@jenstroeger
Copy link

Hello,

I’m seeing several deprecation warnings like

/path/to/.venv/lib/python3.13/site-packages/webob/cookies.py:238: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
  v = datetime.utcnow() + v

and other utcnow() related calls. Are there any plans to address this issue soon? Happy to provide a PR.

@mmerickel
Copy link
Member

I have no concerns about any internal fixes - but I'm worried about areas where it'll hit the public api surface.

@jenstroeger
Copy link
Author

Right… by moving from naive utcnow() to aware now(tz=timezone.utc) I ended up moving the whole stack to aware datetimes. Probably a long overdue move anyway.

In the case of WebOb I think a transparent change would be e.g. from

webob/src/webob/cookies.py

Lines 241 to 242 in 39d5af3

if isinstance(v, timedelta):
v = datetime.utcnow() + v

to

 if isinstance(v, timedelta): 
     v = (datetime.now(tz=timezone.utc) + v).replace(tzinfo=None)

This would be a drop-in change to address the deprecation, but could probably be simplified case by case.

Shouldn’t that address your concern about the public API surface?

@mmerickel
Copy link
Member

mmerickel commented Dec 9, 2024

I guess I'm roping in the reason for the deprecation - not just how to workaround the warning.

The goal of the deprecation is to get people to stop using naive datetimes and/or moving toward assuming that a naive datetime is "local" tz instead of UTC (because this is consistent with the stdlib apis and how they handle naive datetimes).

So sure, if we are just tackling the warning then yeah you can simply replace usages of datetime.utcnow() with datetime.now(datetime.UTC).replace(tzinfo=None) and we are done.

I was assuming you were also proposing the rest, in which you're actually changing the library to use tz-aware datetime objects which is a much bigger change.

Can you clarify your proposal?

@mmerickel
Copy link
Member

To be clear - changing webob to expect tz-aware datetimes and expose tz-aware datetimes at the public api surface is secondary and much more controversial - we'll need to do that carefully.

@jenstroeger
Copy link
Author

[…] we'll need to do that carefully.

Agreed. But mixing aware and naive datetimes also requires care because they can’t be compared. So I think the question becomes:

  1. Just address the utcnow() deprecation warnings and maintain the external interface (see above); or
  2. Create a breaking change and migrate the package to aware and aware only datetimes.

@mmerickel
Copy link
Member

Well let’s break it into two separate units of work if it's ok to you. But your choice.

This datetime to tz-aware thing is like the python 3 change to Unicode but even more subtle imo. Personally to consider the second part I need to know more about what APIs are affected. I know cookies come to mind immediately and cache headers but perhaps there are more.

@mmerickel
Copy link
Member

mmerickel commented Dec 10, 2024

Obviously we can continue to accept naive datetime objects and treat them as we always have (as utc for now??) which may be inconsistent with the stdlib but bw-compat at least.

The biggest issue is where we expose a datetime for a user to consume because it will absolutely break for them if it becomes tz-aware.

@jenstroeger
Copy link
Author

How about we start with a PR that replaces all deprecated naive utcnow() calls with aware now(timezone.utc) calls and, depending on context, either

  • strips the aware datetime of its timezone resulting in a naive UTC datetime (just like utcnow() would deliver); or
  • continues with the aware datetime if required.

That should be drop-in change and would give us a good idea which places will be affected by the change. We can take this discussion from there.

@mmerickel
Copy link
Member

Yeah that sounds the most comfortable to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants