Skip to content

gh-152305: Fix pure-Python time.strftime AttributeError on %Y/%G/%C/%F#152306

Open
tonghuaroot wants to merge 3 commits into
python:mainfrom
tonghuaroot:fix-gh-152305-strftime-time-year
Open

gh-152305: Fix pure-Python time.strftime AttributeError on %Y/%G/%C/%F#152306
tonghuaroot wants to merge 3 commits into
python:mainfrom
tonghuaroot:fix-gh-152305-strftime-time-year

Conversation

@tonghuaroot

@tonghuaroot tonghuaroot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

_wrap_strftime in the pure-Python datetime implementation reads
object.year in its year-normalization branch. When strftime is called on a
datetime.time (which has no .year), this raises
AttributeError: 'time' object has no attribute 'year' for the %Y, %G, %C
and %F directives. The crash happens in the branch guard itself, before the
_need_normalize_century() platform check, so it occurs on every platform.

The C accelerator is correct: a time has no date, so strftime fills the
1900-01-01 placeholder and returns '1900', '19', '1900-01-01' and '1900'
respectively.

The year being formatted is timetuple[0], which is 1900 for a time and
object.year for a date/datetime. This replaces object.year with
timetuple[0] at both occurrences, fixing time and leaving date/datetime
behaviour unchanged: the new pure-Python output equals the long-standing C
accelerator output.

Tests in TestTime.test_strftime assert the four directives, and run under both
the C and pure implementations via the test_datetime parametrization.

Comment thread Lib/_pydatetime.py Outdated
@@ -273,11 +273,11 @@ def _wrap_strftime(object, format, timetuple):
# Note that datetime(1000, 1, 1).strftime('%G') == '1000' so
# year 1000 for %G can go on the fast path.
elif ((ch in 'YG' or ch in 'FC') and

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.

Let's also tidy this up, it was left in this odd state after 719e5c3:

elif (ch in 'YGFC' and timetuple[0] < 1000 and _need_normalize_century()):

Comment on lines +1 to +3
Fix :meth:`datetime.time.strftime` raising :exc:`AttributeError` for the
``%Y``, ``%G``, ``%C`` and ``%F`` directives in the pure-Python
implementation. Patch by tonghuaroot.

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.

Suggested change
Fix :meth:`datetime.time.strftime` raising :exc:`AttributeError` for the
``%Y``, ``%G``, ``%C`` and ``%F`` directives in the pure-Python
implementation. Patch by tonghuaroot.
Fix the pure-Python :meth:`datetime.time.strftime` implementation raising :exc:`AttributeError` for the
year directives. Patch by tonghuaroot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting review needs backport to 3.14 bugs and security fixes needs backport to 3.15 pre-release feature fixes, bugs and security fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants