https://github.com/python/cpython/commit/326f7f74cd38d681c24d6c7ab7a5e213fa7d0073
commit: 326f7f74cd38d681c24d6c7ab7a5e213fa7d0073
branch: main
author: Vyron Vasileiadis <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-09-07T19:02:35Z
summary:

gh-156963: Raise TypeError when concatenating complexstr with another type 
(GH-156964)

complexstr_concat() is the sq_concat slot and returned NotImplemented
for a non-complexstr operand.  PyNumber_Add() returns an sq_concat
result verbatim, so the singleton reached Python code instead of a
TypeError, and an augmented assignment rebound the name to it.

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 389cd043d6c0f3..a75b95d988b070 100644
--- a/Lib/test/test_curses.py
+++ b/Lib/test/test_curses.py
@@ -796,6 +796,9 @@ def test_complexstr(self):
         self.assertEqual(str(s[1:]), 'bc')
         self.assertEqual(str(s[::-1]), 'cbA')
         self.assertEqual(str(s + curses.complexstr(['Z'])), 'AbcZ')
+        # Concatenating anything else raises instead of returning 
NotImplemented.
+        self.assertRaises(TypeError, lambda: s + 'Z')
+        self.assertRaises(TypeError, lambda: s + cc('Z'))
         # The empty complexstr.
         self.assertEqual(len(curses.complexstr([])), 0)
         self.assertEqual(str(curses.complexstr('')), '')
diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c
index 2ff15dd31d2180..781b39628bfa31 100644
--- a/Modules/_cursesmodule.c
+++ b/Modules/_cursesmodule.c
@@ -1590,7 +1590,10 @@ complexstr_concat(PyObject *a, PyObject *b)
 {
     cursesmodule_state *state = get_cursesmodule_state_by_cls(Py_TYPE(a));
     if (!Py_IS_TYPE(b, state->complexstr_type)) {
-        Py_RETURN_NOTIMPLEMENTED;
+        PyErr_Format(PyExc_TypeError,
+                     "can only concatenate complexstr to complexstr, not %T",
+                     b);
+        return NULL;
     }
     PyCursesComplexStrObject *sa = _PyCursesComplexStrObject_CAST(a);
     PyCursesComplexStrObject *sb = _PyCursesComplexStrObject_CAST(b);

_______________________________________________
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]

Reply via email to