Skip to content

gh-154892: Fix PyLong_AsLong() error checks in _zoneinfo - #154901

Open
BHUVANSH855 wants to merge 4 commits into
python:mainfrom
BHUVANSH855:fix-zoneinfo-minus-one
Open

gh-154892: Fix PyLong_AsLong() error checks in _zoneinfo#154901
BHUVANSH855 wants to merge 4 commits into
python:mainfrom
BHUVANSH855:fix-zoneinfo-minus-one

Conversation

@BHUVANSH855

@BHUVANSH855 BHUVANSH855 commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Fix Modules/_zoneinfo.c:get_local_timestamp() to correctly distinguish a legitimate -1 result from PyLong_AsLong() from an actual conversion error by checking PyErr_Occurred(), matching the documented C API behavior and the pure-Python implementation.

The previous implementation treated any -1 return value from PyLong_AsLong() as an error, even when no exception was set. This caused datetime subclasses overriding hour, minute, or second to return -1 to incorrectly raise an exception in the C accelerator.

This PR also adds a regression test covering datetime subclasses whose hour, minute, and second properties return -1.

Issue

Closes issue gh-154892

Comment thread Lib/test/test_zoneinfo/test_zoneinfo.py Outdated
Comment thread Modules/_zoneinfo.c
@@ -2311,7 +2311,7 @@ get_local_timestamp(PyObject *dt, int64_t *local_ts)
}
hour = PyLong_AsLong(num);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not exactly the issue, but related. What if a subclass returns 2**40? Maybe PyLong_AsInt can be used.

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.

That's a good point. I hadn't considered oversized integer values like 2**40. Since this PR is focused on fixing the -1 sentinel handling from PyLong_AsLong(), I'd prefer to keep that as a separate change if we decide PyLong_AsInt() is the better choice.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ok. Could you open an issue for this so we do not forget?

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.

Sure, I'll investigate this further and open a separate issue to track it so it doesn't get lost.

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.

Thanks for pointing this out! I investigated it further.

The C implementation currently uses PyObject_GetAttrString() + PyLong_AsLong() for datetime subclasses, but the pure Python implementation follows the same approach:

(dt.toordinal() - EPOCHORDINAL) * 86400 + dt.hour * 3600 + dt.minute * 60 + dt.second

So both implementations intentionally consult the subclass-visible hour, minute, and second attributes.

I also tested subclasses returning very large values (e.g. 10**12), and both the C and pure Python implementations behave the same way. This means switching to PyLong_AsInt() in the C implementation would only narrow the accepted range there, while the pure Python implementation would continue to accept arbitrarily large values, resulting in inconsistent behavior between the two implementations.

It seems the underlying question is whether ZoneInfo should be consulting overridden subclass attributes at all, rather than whether PyLong_AsLong() should be replaced with PyLong_AsInt().

@BHUVANSH855
BHUVANSH855 requested a review from eendebakpt July 30, 2026 06:29
@johnslavik

Copy link
Copy Markdown
Member

I'll change "Closes: gh-154892" in your PR description to "Closes issue gh-154892", because the use of "closes" keyword would close the issue immediately after this PR is merged and before 3 other backport PRs of your change to our maintenance branches are merged. We want to close the issue after the backport PRs are merged.

Comment thread Lib/test/test_zoneinfo/test_zoneinfo.py Outdated
Comment thread Misc/NEWS.d/next/Library/2026-07-29-21-37-39.gh-issue-154892.eQyJ3Z.rst Outdated
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.13 bugs and security fixes 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.

4 participants