Skip to content

Replace deprecated datetime.utcnow() with timezone-aware equivalent#61

Open
mpasternak wants to merge 5 commits into
infrae:masterfrom
mpasternak:fix/datetime-utcnow-deprecation
Open

Replace deprecated datetime.utcnow() with timezone-aware equivalent#61
mpasternak wants to merge 5 commits into
infrae:masterfrom
mpasternak:fix/datetime-utcnow-deprecation

Conversation

@mpasternak
Copy link
Copy Markdown
Contributor

Summary

datetime.datetime.utcnow() has been deprecated since Python 3.12 and is scheduled for removal in a future Python version:

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).

The only call site in the codebase is XMLTreeServer._outputBasicEnvelope in src/oaipmh/server.py, which stamps the <responseDate> element of every OAI-PMH response.

Change

# Before
datetime.utcnow().replace(microsecond=0)

# After
datetime.now(timezone.utc).replace(microsecond=0, tzinfo=None)

datetime_to_datestamp() in oaipmh/datestamp.py asserts dt.tzinfo is None (only accepts naive datetimes), so after obtaining a timezone-aware UTC value we strip tzinfo back off. The resulting responseDate string in the OAI-PMH response is byte-for-byte identical to what the old code produced.

Why this matters

Downstream projects running pytest with filterwarnings = error (or -W error) fail with a 500 on every OAI-PMH verb because the DeprecationWarning is promoted to an exception during response rendering. The change is trivial and semantically transparent.

Test plan

  • Manual smoke-test: datetime_to_datestamp(datetime.now(timezone.utc).replace(microsecond=0, tzinfo=None)) produces the same YYYY-MM-DDTHH:MM:SSZ format as before, with no DeprecationWarning on Python 3.13.
  • CI runs existing src/oaipmh/tests/ on a supported Python version. (Note: on Python 3.12+ the existing tests fail at collection with ImportError: cannot import name 'makeSuite' from 'unittest' — an unrelated issue since unittest.makeSuite was removed in 3.12.)

🤖 Generated with Claude Code

Michał Pasternak and others added 5 commits July 6, 2017 02:42
`datetime.datetime.utcnow()` is deprecated since Python 3.12 and
scheduled for removal in a future version:

    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).

`datetime_to_datestamp()` in `oaipmh/datestamp.py` asserts that the
input has `tzinfo is None`, so we convert the timezone-aware UTC
value back to naive with `.replace(tzinfo=None)` before passing it
in. The resulting `responseDate` string in the OAI-PMH response is
unchanged.

This is the only `datetime.utcnow()` call in the codebase; after
this change, pyoai no longer emits `DeprecationWarning` for it on
Python 3.12+.
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.

2 participants