Skip to content

GH-70647: Remove support for %d (and deprecate for %e) without year in strptime()#144570

Merged
gpshead merged 10 commits intopython:mainfrom
StanFromIreland:e-d-no-year
Apr 15, 2026
Merged

GH-70647: Remove support for %d (and deprecate for %e) without year in strptime()#144570
gpshead merged 10 commits intopython:mainfrom
StanFromIreland:e-d-no-year

Conversation

@StanFromIreland
Copy link
Copy Markdown
Member

@StanFromIreland StanFromIreland commented Feb 7, 2026

@encukou
Copy link
Copy Markdown
Member

encukou commented Feb 9, 2026

This also updates the deprecation period for %d to the current preference in PEP-387 (5 years, since 3.13); planning to end the deprecation period for both %d and %e in 3.18.

This looks good to me. @gpshead, are you OK with it?

@gpshead
Copy link
Copy Markdown
Member

gpshead commented Feb 9, 2026

Including %e makes sense (an oversight from the original change).

I do not believe pushing this deprecation out to 3.18 is a great idea though... We will have people dealing with production outages on leap day yet again due to bad date parsing around 2028-02-29 if the deprecation has not already shipped in a release that has seen wide adoption before that time.

3.15 will be widely adopted by 2028-02 as it should've shipped in several major long term support os distro releases that people will actually be using by 2028.
3.16 will have some adoption (maybe enough to have forced a fix to the broader ecosystem's errant strptime calls?).
3.17 probably not in wide use.
3.18 won't yet exist.

Most things I like giving a long deprecation grace period on, this one is a ticking time bomb every 4 years that IMNSHO really does need action to be taken in a timely manner. One of the rare cases where forcing the issue is a good thing.

I'm not gonna block pushing it out, but I suggest reconsidering.

@StanFromIreland
Copy link
Copy Markdown
Member Author

Including %e makes sense (an oversight from the original change).

It wasn't implemented at the time.

production outages on leap day

In my opinion, this really depends on what we decide to do to fix the issue. If we are going to always raise an error, that itself will cause disruption, leap day or not, so I'd be in favour of a longer deprecation period.

If we are to change the default year... I haven't considered what side effects that would have. I'd imagine there are people relying on the specific year ($1900$). It is also documented, and is not specified as an implementation detail.

@encukou
Copy link
Copy Markdown
Member

encukou commented Feb 10, 2026

3.15 will be widely adopted by 2028-02 as it should've shipped in several major long term support os distro releases that people will actually be using by 2028.

We can split the removals. Make %d fail now; deprecate %e and plan removal for 3.17.

If we are going to always raise an error, that itself will cause disruption, leap day or not, so I'd be in favour of a longer deprecation period.

The major difference is that if we always raise an error, it will show up in testing environments after a Python upgrade, giving you time to roll back.
If it only fails when the input is a leap day, and you use current date as input, your production app will go down on 2028-02-29.

If we are to change the default year... I haven't considered what side effects that would have. I'd imagine there are people relying on the specific year ( 1900 ).

Yeah, this smells too much like silently returning a wrong value to avoid an exception.

@StanFromIreland
Copy link
Copy Markdown
Member Author

We can split the removals. Make %d fail now; deprecate %e and plan removal for 3.17.

If we are to do it, I'd rather do both at once, %e was illegitimately (i.e. after the feature freeze) added to 3.13/3.14, the first version it technically should be in and is documented in is 3.15.

@encukou
Copy link
Copy Markdown
Member

encukou commented Apr 14, 2026

Sorry, I let this stall.

Mistakes were made. As far as users are concerned, this is in 3.13.

I still think splitting the removal dates is best here. As Greg notes, there's a good reason to remove %d now; %s needs some deprecation period (and I doubt it'll see wide use if it's deprecated now).

@StanFromIreland
Copy link
Copy Markdown
Member Author

Ok, we can do %d in 3.15.

For %s, did you mean %e? I would still lean towards doing both, it was "private" in 3.13/14.

# Conflicts:
#	Doc/deprecations/pending-removal-in-3.18.rst
#	Lib/test/test_time.py
@encukou
Copy link
Copy Markdown
Member

encukou commented Apr 14, 2026

Yeah, %e, sorry.

What do you mean by “private”? It's present in 3.14.0; doc-wise it's covered either by “full set of format codes supported varies across platforms” or PEP 387's “if something is not documented at all, it is not automatically considered private”.

@StanFromIreland StanFromIreland requested a review from gpshead April 14, 2026 16:03
@StanFromIreland StanFromIreland changed the title GH-70647: Include %e in deprecation of strptime() day of month parsing without a year GH-70647: Remove support for %d (and deprecate for %e) without year in strptime() Apr 14, 2026
@StanFromIreland
Copy link
Copy Markdown
Member Author

StanFromIreland commented Apr 14, 2026

Removed support for %d, and deprecated and scheduled removal for %e for 3.17.

I'm not sure how to avoid confusing the docs, should we keep two version changeds (one for deprecation and one for removal) or have just one?

Copy link
Copy Markdown
Member

@gpshead gpshead left a comment

Choose a reason for hiding this comment

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

If the docs need further massaging it can be done as followups.

@gpshead gpshead merged commit d0e7c6a into python:main Apr 15, 2026
55 checks passed
@StanFromIreland StanFromIreland deleted the e-d-no-year branch April 15, 2026 06:31
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