]> granicus.if.org Git - python/commitdiff
Issue #11223: Replace threading._info() by sys.thread_info
authorVictor Stinner <victor.stinner@haypocalc.com>
Sat, 30 Apr 2011 12:53:09 +0000 (14:53 +0200)
committerVictor Stinner <victor.stinner@haypocalc.com>
Sat, 30 Apr 2011 12:53:09 +0000 (14:53 +0200)
13 files changed:
Doc/library/sys.rst
Doc/library/threading.rst
Doc/whatsnew/3.3.rst
Include/pythread.h
Lib/_dummy_thread.py
Lib/test/test_os.py
Lib/test/test_sys.py
Lib/test/test_threading.py
Lib/test/test_threadsignals.py
Lib/threading.py
Modules/_threadmodule.c
Python/sysmodule.c
Python/thread.c

index ba781b3a6d0ec9cc064c3b0ca3c80f0a1a07f756..a34c4977c92e1313075198832270378ce92d3cc7 100644 (file)
@@ -961,6 +961,35 @@ always available.
        to a console and Python apps started with :program:`pythonw`.
 
 
+.. data:: thread_info
+
+   A :term:`struct sequence` holding information about the thread
+   implementation.
+
+   +------------------+---------------------------------------------------------+
+   | Attribute        | Explanation                                             |
+   +==================+=========================================================+
+   | :const:`name`    | Name of the thread implementation:                      |
+   |                  |                                                         |
+   |                  |  * ``'nt'``: Windows threads                            |
+   |                  |  * ``'os2'``: OS/2 threads                              |
+   |                  |  * ``'pthread'``: POSIX threads                         |
+   |                  |  * ``'solaris'``: Solaris threads                       |
+   +------------------+---------------------------------------------------------+
+   | :const:`lock`    | Name of the lock implementation:                        |
+   |                  |                                                         |
+   |                  |  * ``'semaphore'``: a lock uses a semaphore             |
+   |                  |  * ``'mutex+cond'``: a lock uses a mutex                |
+   |                  |    and a condition variable                             |
+   |                  |  * ``None`` if this information is unknown              |
+   +------------------+---------------------------------------------------------+
+   | :const:`version` | Name and version of the thread library. It is a string, |
+   |                  | or ``None`` if these informations are unknown.          |
+   +------------------+---------------------------------------------------------+
+
+   .. versionadded:: 3.3
+
+
 .. data:: tracebacklimit
 
    When this variable is set to an integer value, it determines the maximum number
index dd2226d67f59b267f484db3a5ba869aaf5c234e9..df47045ffb5d334ebdab847dbcb04696744288ed 100644 (file)
@@ -175,30 +175,6 @@ This module defines the following functions and objects:
    Availability: Windows, systems with POSIX threads.
 
 
-.. function:: _info()
-
-   Return a dictionary with informations about the thread implementation.
-   The ``'name'`` key gives the name of the thread implementation (string):
-
-    * ``'nt'``: Windows threads
-    * ``'os2'``: OS/2 threads
-    * ``'pthread'``: POSIX threads
-    * ``'solaris'``: Solaris threads
-
-   POSIX threads have two more keys:
-
-    * ``'lock_implementation'`` (string): name of the lock
-      implementation
-
-      * ``'semaphore'``: a lock uses a semaphore
-      * ``'mutex+cond'``: a lock uses a mutex and a condition variable
-
-    * ``'pthread_version'`` (string, optional): name and version of the pthread
-      library
-
-   .. versionadded:: 3.3
-
-
 This module also defines the following constant:
 
 .. data:: TIMEOUT_MAX
index a26fe7587f5f750424e795e35341794730c6d269..93da9d8555a6c1bde299f37d07d34ecaeeef06d8 100644 (file)
@@ -112,11 +112,11 @@ connection when done::
 
 (Contributed by Giampaolo RodolĂ  in :issue:`9795`)
 
-threading
----------
+sys
+---
 
-* The :mod:`threading` module has a new :func:`~threading._info` function which
-  provides informations about the thread implementation.
+* The :mod:`sys` module has a new :func:`~sys.thread_info` :term:`struct
+  sequence` holding informations about the thread implementation.
 
   (:issue:`11223`)
 
index 9a35e5d01c4d610bf3595ee789bd63b768b468c6..6e9f30337fb9860ada13d59620e838c1c8b9011a 100644 (file)
@@ -74,7 +74,7 @@ PyAPI_FUNC(void) PyThread_release_lock(PyThread_type_lock);
 PyAPI_FUNC(size_t) PyThread_get_stacksize(void);
 PyAPI_FUNC(int) PyThread_set_stacksize(size_t);
 
-PyAPI_FUNC(PyObject*) _PyThread_Info(void);
+PyAPI_FUNC(PyObject*) PyThread_GetInfo(void);
 
 /* Thread Local Storage (TLS) API */
 PyAPI_FUNC(int) PyThread_create_key(void);
index f2465a9c99d4769b4ff3f084ee59d4219d6573bd..13b1f26965a201019ab3ccf91e7a6da2fb51ee8f 100644 (file)
@@ -149,6 +149,3 @@ def interrupt_main():
     else:
         global _interrupt
         _interrupt = True
-
-def info():
-    return {'name': 'dummy'}
index 543241294c669b94856e41626e2e6f04da466866..aa9ff5dfe9e7f3f008170c731dcb8c6799bdab64 100644 (file)
@@ -27,15 +27,10 @@ except ImportError:
 # and unmaintained) linuxthreads threading library.  There's an issue
 # when combining linuxthreads with a failed execv call: see
 # http://bugs.python.org/issue4970.
-USING_LINUXTHREADS = False
-if threading:
-    info = threading._info()
-    try:
-        pthread_version = info['pthread_version']
-    except KeyError:
-        pass
-    else:
-        USING_LINUXTHREADS = pthread_version.startswith("linuxthreads")
+if hasattr(sys, 'thread_info') and sys.thread_info.version:
+    USING_LINUXTHREADS = sys.thread_info.version.startswith("linuxthreads")
+else:
+    USING_LINUXTHREADS = False
 
 # Tests creating TESTFN
 class FileTests(unittest.TestCase):
index e18019c15cc720513dbddca1b0036297c0935138..61b2676c4492b7e84b51598da8fd84304dd3ea6d 100644 (file)
@@ -474,6 +474,14 @@ class SysModuleTest(unittest.TestCase):
         if not sys.platform.startswith('win'):
             self.assertIsInstance(sys.abiflags, str)
 
+    @unittest.skipUnless(hasattr(sys, 'thread_info'),
+                         'Threading required for this test.')
+    def test_thread_info(self):
+        info = sys.thread_info
+        self.assertTrue(len(info), 3)
+        self.assertIn(info.name, ('nt', 'os2', 'pthread', 'solaris', None))
+        self.assertIn(info.lock, ('semaphore', 'mutex+cond', None))
+
     def test_43581(self):
         # Can't use sys.stdout, as this is a StringIO object when
         # the test runs under regrtest.
index fd63d39367d014b238a0cfb5a0dc183e2a72f217..66a04c83f3bfee6eee04c3388b874754dd2dd146 100644 (file)
@@ -719,16 +719,6 @@ class BarrierTests(lock_tests.BarrierTests):
     barriertype = staticmethod(threading.Barrier)
 
 
-class MiscTests(unittest.TestCase):
-    def test_info(self):
-        info = threading._info()
-        self.assertIn(info['name'],
-                      'nt os2 pthread solaris'.split())
-        if info['name'] == 'pthread':
-            self.assertIn(info['lock_implementation'],
-                          ('semaphore', 'mutex+cond'))
-
-
 def test_main():
     test.support.run_unittest(LockTests, PyRLockTests, CRLockTests, EventTests,
                               ConditionAsRLockTests, ConditionTests,
@@ -736,7 +726,7 @@ def test_main():
                               ThreadTests,
                               ThreadJoinOnShutdown,
                               ThreadingExceptionTests,
-                              BarrierTests, MiscTests,
+                              BarrierTests,
                               )
 
 if __name__ == "__main__":
index b0bc6072851177aa852bdf5991489aa2f9559ded..f975a75e85d76c9f5fc5f5d5a0ca3173ecca045b 100644 (file)
@@ -14,9 +14,8 @@ if sys.platform[:3] in ('win', 'os2') or sys.platform=='riscos':
 process_pid = os.getpid()
 signalled_all=thread.allocate_lock()
 
-info = thread.info()
-USING_PTHREAD_COND = (info['name'] == 'pthread'
-                      and info['lock_implementation'] == 'mutex+cond')
+USING_PTHREAD_COND = (sys.thread_info.name == 'pthread'
+                      and sys.thread_info.lock == 'mutex+cond')
 
 def registerSignals(for_usr1, for_usr2, for_alrm):
     usr1 = signal.signal(signal.SIGUSR1, for_usr1)
index 28c214667148cc6ffa0d3e101b0d20b57932f5d6..fafe7792f5653a59c6234e6ff838a8fd45004718 100644 (file)
@@ -19,7 +19,7 @@ from collections import deque
 
 __all__ = ['active_count', 'Condition', 'current_thread', 'enumerate', 'Event',
            'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread', 'Barrier',
-           'Timer', 'setprofile', 'settrace', 'local', 'stack_size', '_info']
+           'Timer', 'setprofile', 'settrace', 'local', 'stack_size']
 
 # Rename some stuff so "from threading import *" is safe
 _start_new_thread = _thread.start_new_thread
@@ -31,7 +31,6 @@ try:
 except AttributeError:
     _CRLock = None
 TIMEOUT_MAX = _thread.TIMEOUT_MAX
-_info = _thread.info
 del _thread
 
 
index 1aee77b5f72242ff1d482fdde1233ba06a43d74f..8881427269c2883722f64a929b69306d62040083 100644 (file)
@@ -1227,17 +1227,6 @@ requiring allocation in multiples of the system memory page size\n\
 (4kB pages are common; using multiples of 4096 for the stack size is\n\
 the suggested approach in the absence of more specific information).");
 
-static PyObject *
-thread_info(PyObject *self)
-{
-    return _PyThread_Info();
-}
-
-PyDoc_STRVAR(thread_info_doc,
-"info() -> dict\n\
-\n\
-Informations about the thread implementation.");
-
 static PyMethodDef thread_methods[] = {
     {"start_new_thread",        (PyCFunction)thread_PyThread_start_new_thread,
      METH_VARARGS, start_new_doc},
@@ -1259,8 +1248,6 @@ static PyMethodDef thread_methods[] = {
      METH_NOARGS, _count_doc},
     {"stack_size",              (PyCFunction)thread_stack_size,
      METH_VARARGS, stack_size_doc},
-    {"info",                    (PyCFunction)thread_info,
-     METH_NOARGS, thread_info_doc},
     {NULL,                      NULL}           /* sentinel */
 };
 
index fdf361fa8b4c65569b2742a1dbb0b55d1713fc5a..b5492035365a3b32d9cbe2c680f583b029669dc4 100644 (file)
@@ -17,6 +17,7 @@ Data members:
 #include "Python.h"
 #include "code.h"
 #include "frameobject.h"
+#include "pythread.h"
 
 #include "osdefs.h"
 
@@ -1251,20 +1252,21 @@ PyDoc_STR(
 "\n\
 Static objects:\n\
 \n\
-float_info -- a dict with information about the float implementation.\n\
+builtin_module_names -- tuple of module names built into this interpreter\n\
+copyright -- copyright notice pertaining to this interpreter\n\
+exec_prefix -- prefix used to find the machine-specific Python library\n\
+executable -- pathname of this Python interpreter\n\
+float_info -- a struct sequence with information about the float implementation.\n\
+float_repr_style -- string indicating the style of repr() output for floats\n\
+hexversion -- version information encoded as a single integer\n\
 int_info -- a struct sequence with information about the int implementation.\n\
 maxsize -- the largest supported length of containers.\n\
 maxunicode -- the largest supported character\n\
-builtin_module_names -- tuple of module names built into this interpreter\n\
-version -- the version of this interpreter as a string\n\
-version_info -- version information as a named tuple\n\
-hexversion -- version information encoded as a single integer\n\
-copyright -- copyright notice pertaining to this interpreter\n\
 platform -- platform identifier\n\
-executable -- pathname of this Python interpreter\n\
 prefix -- prefix used to find the Python library\n\
-exec_prefix -- prefix used to find the machine-specific Python library\n\
-float_repr_style -- string indicating the style of repr() output for floats\n\
+thread_info -- a struct sequence with information about the thread implementation.\n\
+version -- the version of this interpreter as a string\n\
+version_info -- version information as a named tuple\n\
 "
 )
 #ifdef MS_WINDOWS
@@ -1611,6 +1613,10 @@ _PySys_Init(void)
                         PyUnicode_FromString("legacy"));
 #endif
 
+#ifdef WITH_THREAD
+    SET_SYS_FROM_STRING("thread_info", PyThread_GetInfo());
+#endif
+
 #undef SET_SYS_FROM_STRING
     if (PyErr_Occurred())
         return NULL;
index 1f15a22e2fc0d67c9683e08b5427bda58c790985..c7d17d60e98c1d53c7614ab2dbe9bf4e02d433d4 100644 (file)
@@ -7,7 +7,6 @@
 
 #include "Python.h"
 
-
 #ifndef _POSIX_THREADS
 /* This means pthreads are not implemented in libc headers, hence the macro
    not present in unistd.h. But they still can be implemented as an external
@@ -415,26 +414,51 @@ PyThread_ReInitTLS(void)
 
 #endif /* Py_HAVE_NATIVE_TLS */
 
+PyDoc_STRVAR(threadinfo__doc__,
+"sys.thread_info\n\
+\n\
+A struct sequence holding information about the thread implementation.");
+
+static PyStructSequence_Field threadinfo_fields[] = {
+    {"name",    "name of the thread implementation"},
+    {"lock",    "name of the lock implementation"},
+    {"version", "name and version of the thread library"},
+    {0}
+};
+
+static PyStructSequence_Desc threadinfo_desc = {
+    "sys.thread_info",           /* name */
+    threadinfo__doc__,           /* doc */
+    threadinfo_fields,           /* fields */
+    3
+};
+
+static PyTypeObject ThreadInfoType;
+
 PyObject*
-_PyThread_Info(void)
+PyThread_GetInfo(void)
 {
-    PyObject *info, *value;
-    int ret;
+    PyObject *threadinfo, *value;
+    int pos = 0;
 #if (defined(_POSIX_THREADS) && defined(HAVE_CONFSTR) \
      && defined(_CS_GNU_LIBPTHREAD_VERSION))
     char buffer[255];
     int len;
 #endif
 
-    info = PyDict_New();
-    if (info == NULL)
+    if (ThreadInfoType.tp_name == 0)
+        PyStructSequence_InitType(&ThreadInfoType, &threadinfo_desc);
+
+    threadinfo = PyStructSequence_New(&ThreadInfoType);
+    if (threadinfo == NULL)
         return NULL;
 
     value = PyUnicode_FromString(PYTHREAD_NAME);
-    ret = PyDict_SetItemString(info, "name", value);
-    Py_DECREF(value);
-    if (ret)
-        goto error;
+    if (value == NULL) {
+        Py_DECREF(threadinfo);
+        return NULL;
+    }
+    PyStructSequence_SET_ITEM(threadinfo, pos++, value);
 
 #ifdef _POSIX_THREADS
 #ifdef USE_SEMAPHORES
@@ -442,30 +466,31 @@ _PyThread_Info(void)
 #else
     value = PyUnicode_FromString("mutex+cond");
 #endif
-    if (value == NULL)
+    if (value == NULL) {
+        Py_DECREF(threadinfo);
         return NULL;
-    ret = PyDict_SetItemString(info, "lock_implementation", value);
-    Py_DECREF(value);
-    if (ret)
-        goto error;
+    }
+#else
+    Py_INCREF(Py_None);
+    value = Py_None;
+#endif
+    PyStructSequence_SET_ITEM(threadinfo, pos++, value);
 
-#if defined(HAVE_CONFSTR) && defined(_CS_GNU_LIBPTHREAD_VERSION)
+#if (defined(_POSIX_THREADS) && defined(HAVE_CONFSTR) \
+     && defined(_CS_GNU_LIBPTHREAD_VERSION))
+    value = NULL;
     len = confstr(_CS_GNU_LIBPTHREAD_VERSION, buffer, sizeof(buffer));
-    if (0 < len && len < sizeof(buffer)) {
+    if (1 < len && len < sizeof(buffer)) {
         value = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
         if (value == NULL)
-            goto error;
-        ret = PyDict_SetItemString(info, "pthread_version", value);
-        Py_DECREF(value);
-        if (ret)
-            goto error;
+            PyErr_Clear();
     }
+    if (value == NULL)
 #endif
-#endif
-
-    return info;
-
-error:
-    Py_DECREF(info);
-    return NULL;
+    {
+        Py_INCREF(Py_None);
+        value = Py_None;
+    }
+    PyStructSequence_SET_ITEM(threadinfo, pos++, value);
+    return threadinfo;
 }