@@ -784,12 +784,15 @@ get_thread_info(PyObject *self, PyObject *args)
784784 long id_is_valid ;
785785 /* The additional optional argument flags is currently intentionally
786786 * undocumented. The lower order flag bits are reserved for future public
787- * applications. If the flag bit 31 is set, the returned tuple contains
788- * the watchdog list as an additional item. The Stackless test suite uses
789- * this feature to ensure that the list is empty at start and end of each
790- * test.
787+ * applications.
788+ * If the flag bit 30 is set, the values of serial, serial_last_jump and
789+ * initial_stub are appended to the result. The Stackless test suite uses them.
790+ * If the flag bit 31 is set, the watchdog list is appended to the result.
791+ * The Stackless test suite uses this feature to ensure that the list is empty at
792+ * start and end of each test.
791793 */
792794 unsigned long flags = 0 ;
795+ PyObject * retval ;
793796
794797 if (!PyArg_ParseTuple (args , "|O!k:get_thread_info" , & PyLong_Type , & thread_id , & flags ))
795798 return NULL ;
@@ -807,11 +810,44 @@ get_thread_info(PyObject *self, PyObject *args)
807810 RUNTIME_ERROR ("Thread id not found" , NULL );
808811 }
809812
810- return Py_BuildValue (( flags & ( 1ul << 31 )) ? "(OOiO)" : "(OOi)" ,
813+ retval = Py_BuildValue ("(OOi)" ,
811814 ts -> st .main ? (PyObject * ) ts -> st .main : Py_None ,
812815 ts -> st .runcount ? (PyObject * ) ts -> st .current : Py_None ,
813- ts -> st .runcount ,
814- ts -> st .watchdogs ? ts -> st .watchdogs : Py_None );
816+ ts -> st .runcount
817+ );
818+
819+ if (retval && (flags & (1ul <<30 ))) {
820+ Py_ssize_t retsize = PyTuple_GET_SIZE (retval );
821+ /* Append the serial numbers */
822+ PyObject * serial , * serial_last_jump ;
823+ serial = PyLong_FromLongLong (ts -> st .serial );
824+ if (serial == NULL ) {
825+ Py_DECREF (retval );
826+ return NULL ;
827+ }
828+ serial_last_jump = PyLong_FromLongLong (ts -> st .serial_last_jump );
829+ if (serial == NULL ) {
830+ Py_DECREF (retval );
831+ return NULL ;
832+ }
833+ if (!_PyTuple_Resize (& retval , retsize + 3 )) {
834+ PyTuple_SET_ITEM (retval , retsize , serial ); /* steals a ref to serial */
835+ PyTuple_SET_ITEM (retval , retsize + 1 , serial_last_jump ); /* steals a ref to serial_last_jump */
836+ serial = ts -> st .initial_stub ? (PyObject * ) ts -> st .initial_stub : Py_None ;
837+ Py_INCREF (serial );
838+ PyTuple_SET_ITEM (retval , retsize + 2 , serial ); /* steals a ref to serial */
839+ }
840+ }
841+ if (retval && (flags & (1ul <<31 ))) {
842+ Py_ssize_t retsize = PyTuple_GET_SIZE (retval );
843+ /* Append the watchdog list */
844+ if (!_PyTuple_Resize (& retval , retsize + 1 )) {
845+ PyObject * o = ts -> st .watchdogs ? ts -> st .watchdogs : Py_None ;
846+ Py_INCREF (o );
847+ PyTuple_SET_ITEM (retval , retsize , o ); /* steals a ref to o */
848+ }
849+ }
850+ return retval ;
815851}
816852
817853static PyObject *
0 commit comments