Skip to content

Replace to-be-deprecated utcnow() datetime calls with aware now() calls - #475

Closed
jenstroeger wants to merge 1 commit into
Pylons:mainfrom
jenstroeger:replace-naive-utcnow-with-aware-now
Closed

Replace to-be-deprecated utcnow() datetime calls with aware now() calls#475
jenstroeger wants to merge 1 commit into
Pylons:mainfrom
jenstroeger:replace-naive-utcnow-with-aware-now

Conversation

@jenstroeger

@jenstroeger jenstroeger commented Dec 12, 2024

Copy link
Copy Markdown
Contributor

As per issue #473

I didn’t add tests yet, see my comments below. Still need to format the code, but it looks like Windows tests fail because, I suspect, of this data source discrepancy.

@jenstroeger jenstroeger left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few comments below to continue the conversation from issue #473.

Comment thread src/webob/cookies.py Outdated
Comment on lines +242 to +243
v = datetime.utcnow() + v
v = datetime.now(tz=zoneinfo.ZoneInfo("UTC")) + v

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The string formatting below doesn’t care that the datetime object is aware here.

Comment thread src/webob/cookies.py
Comment on lines +245 to 247
if isinstance(v, datetime):
v = v.astimezone(zoneinfo.ZoneInfo("UTC")).timetuple()
elif isinstance(v, date):
v = v.timetuple()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function can receive bytes, str, int but it doesn’t have an else branch to catch any other unexpected type. If for some reason a datetime is passed in then we’ll want to make sure it’s in UTC, hence the adjustment. Also, unless a date object is passed in there shouldn’t be a need to handle those but cookies should always contain a date & time AFAIK.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change would require a test. For the specific utcnow issue I think #480 is probably a good way to go. But this is a good point that isn't handled anywhere else.

Comment thread src/webob/response.py

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All utcnow() are replaced and continue to produce naive datetime objects in UTC.

@mmerickel

Copy link
Copy Markdown
Member

datetime.timezone.utc was added in python 3.2 - is there a reason not to use it in favor of zoneinfo?

@jenstroeger
jenstroeger force-pushed the replace-naive-utcnow-with-aware-now branch from 7b13071 to dcd915a Compare December 13, 2024 00:51
@jenstroeger

Copy link
Copy Markdown
Contributor Author

datetime.timezone.utc was added in python 3.2 - is there a reason not to use it in favor of zoneinfo?

Sigh 🤦🏻‍♂️ Consider that a magnificent brain fart on my side.

@mmerickel mmerickel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jenstroeger

jenstroeger commented Dec 13, 2024

Copy link
Copy Markdown
Contributor Author

@mmerickel what do you think of the above comments/questions, esp #475 (comment)?

@digitalresistor

Copy link
Copy Markdown
Member

Thank you for this, and for the patience on the long review cycle here.

There were three overlapping PRs open against #473 and #430 (this one, #480 and #491), all touching the same lines, so none could be merged alongside the others. I've combined them into #496, where your commit is preserved with you as the author.

Your change to convert an aware datetime to UTC before serializing it carries over as its own bugfix — as @mmerickel noted in review, that's a real problem not handled anywhere else. It now has the test he asked for.

One adjustment worth flagging: the astimezone(timezone.utc) call is gated on v.tzinfo is not None in #496. Applied unconditionally it treats a naive datetime as local time and shifts it by the machine's UTC offset, where WebOb has always read naive datetimes as UTC. Under TZ=America/New_York a naive datetime(2011, 1, 4, 13, 43, 50) serialized as 18:43:50 GMT instead of 13:43:50 GMT. CI runs in UTC, so it doesn't show up there. There's a tz-sensitive regression test for it now.

For the deprecation itself #496 uses the centralized utcnow() helper from #480, which @mmerickel favoured in his review of this PR.

Closing here since the work continues in #496 — it's open for review, not merged yet.

digitalresistor added a commit that referenced this pull request Aug 3, 2026
Combining #475 and #480 leaves one behavior change worth guarding: 475's
unconditional v.astimezone(timezone.utc) treats a *naive* datetime as local
time, shifting it by the machine's UTC offset. WebOb has always treated naive
datetimes as UTC, and CI runs in UTC so the change is invisible there.

Gate the conversion on v.tzinfo, keeping 475's fix for aware datetimes while
leaving naive ones alone, and cover the naive/aware/date paths plus the new
utcnow() helper.
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

Successfully merging this pull request may close these issues.

3 participants