https://github.com/python/cpython/commit/a728080492e6cdcffebbfe11e520a1cf6e7aaee1
commit: a728080492e6cdcffebbfe11e520a1cf6e7aaee1
branch: main
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-08-25T09:22:46Z
summary:
gh-156348: Fix the value of curses.ERR (GH-156349)
Setting the module constants with an unsigned conversion, needed for the
chtype constants that can set bits beyond a 32-bit long, turned ERR from -1
into 18446744073709551615. Set ERR and OK with a signed conversion.
files:
M Lib/test/test_curses.py
M Modules/_cursesmodule.c
diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py
index 13b024941f739b3..389cd043d6c0f39 100644
--- a/Lib/test/test_curses.py
+++ b/Lib/test/test_curses.py
@@ -2984,6 +2984,11 @@ def test_has_extended_color_support(self):
r = curses.has_extended_color_support()
self.assertIsInstance(r, bool)
+ def test_err_and_ok(self):
+ # ERR is negative; it is not a chtype constant.
+ self.assertEqual(curses.ERR, -1)
+ self.assertEqual(curses.OK, 0)
+
def test_type_names(self):
# The curses types report their public module rather than the
# underscore extension that implements them.
diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c
index bd13022261c20ea..2ff15dd31d21803 100644
--- a/Modules/_cursesmodule.c
+++ b/Modules/_cursesmodule.c
@@ -6657,11 +6657,10 @@ curses_init_dict(PyObject *module)
}
/* This was moved from initcurses() because it core dumped on SGI,
where they're not defined until you've called initscr() */
- /* Use long long, not long: a chtype constant (the A_* attributes, ACS_*
- and key codes) can set bits beyond a 32-bit long, which is what long is
- on LLP64 platforms such as Windows -- A_DIM (0x80000000) would otherwise
- be sign-extended to a negative number. long long is at least 64 bits
- everywhere and still represents the negative ERR (-1). */
+ /* Use unsigned long long, not long: a chtype constant (the A_* attributes,
+ ACS_* and key codes) can set bits beyond a 32-bit long, which is what
+ long is on LLP64 platforms such as Windows -- A_DIM (0x80000000) would
+ otherwise be sign-extended to a negative number. */
#define SetDictInt(NAME, VALUE) \
do { \
PyObject *value = PyLong_FromUnsignedLongLong((unsigned long
long)(VALUE)); \
@@ -9419,8 +9418,24 @@ cursesmodule_exec(PyObject *module)
} \
} while (0)
- SetDictInt("ERR", ERR);
- SetDictInt("OK", OK);
+ /* ERR is -1, so it needs a signed conversion, unlike the chtype
+ constants below. */
+#define SetDictSignedInt(NAME, VALUE) \
+ do { \
+ PyObject *value = PyLong_FromLongLong((long long)(VALUE)); \
+ if (value == NULL) { \
+ return -1; \
+ } \
+ int rc = PyDict_SetItemString(module_dict, (NAME), value); \
+ Py_DECREF(value); \
+ if (rc < 0) { \
+ return -1; \
+ } \
+ } while (0)
+
+ SetDictSignedInt("ERR", ERR);
+ SetDictSignedInt("OK", OK);
+#undef SetDictSignedInt
/* Here are some attributes you can add to chars to print */
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]