| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 1e2147b commit aefa7eb
27 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -830,7 +830,7 @@ been created. | |||
| 830 | 830 | the caller should assume no current thread state is available. | |
| 831 | 831 | ||
| 832 | 832 | ||
| 833 | - .. c:function:: int PyThreadState_SetAsyncExc(long id, PyObject *exc) | ||
| 833 | + .. c:function:: int PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc) | ||
| 834 | 834 | ||
| 835 | 835 | Asynchronously raise an exception in a thread. The *id* argument is the thread | |
| 836 | 836 | id of the target thread; *exc* is the exception object to be raised. This | |
@@ -840,6 +840,9 @@ been created. | |||
| 840 | 840 | zero if the thread id isn't found. If *exc* is :const:`NULL`, the pending | |
| 841 | 841 | exception (if any) for the thread is cleared. This raises no exceptions. | |
| 842 | 842 | ||
| 843 | + .. versionchanged:: 3.7 | ||
| 844 | + The type of the *id* parameter changed from :c:type:`long` to | ||
| 845 | + :c:type:`unsigned long`. | ||
| 843 | 846 | ||
| 844 | 847 | .. c:function:: void PyEval_AcquireThread(PyThreadState *tstate) | |
| 845 | 848 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -185,6 +185,16 @@ Deprecated | |||
| 185 | 185 | (Contributed by Serhiy Storchaka in :issue:`28692`.) | |
| 186 | 186 | ||
| 187 | 187 | ||
| 188 | + Changes in the C API | ||
| 189 | + -------------------- | ||
| 190 | + | ||
| 191 | + - The type of results of :c:func:`PyThread_start_new_thread` and | ||
| 192 | + :c:func:`PyThread_get_thread_ident`, and the *id* parameter of | ||
| 193 | + :c:func:`PyThreadState_SetAsyncExc` changed from :c:type:`long` to | ||
| 194 | + :c:type:`unsigned long`. | ||
| 195 | + (Contributed by Serhiy Storchaka in :issue:`6532`.) | ||
| 196 | + | ||
| 197 | + | ||
| 188 | 198 | Removed | |
| 189 | 199 | ======= | |
| 190 | 200 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -108,7 +108,7 @@ typedef struct _ts { | |||
| 108 | 108 | int gilstate_counter; | |
| 109 | 109 | ||
| 110 | 110 | PyObject *async_exc; /* Asynchronous exception to raise */ | |
| 111 | - long thread_id; /* Thread id where this tstate was created */ | ||
| 111 | + unsigned long thread_id; /* Thread id where this tstate was created */ | ||
| 112 | 112 | ||
| 113 | 113 | int trash_delete_nesting; | |
| 114 | 114 | PyObject *trash_delete_later; | |
@@ -200,7 +200,7 @@ PyAPI_FUNC(PyThreadState *) _PyThreadState_UncheckedGet(void); | |||
| 200 | 200 | ||
| 201 | 201 | PyAPI_FUNC(PyThreadState *) PyThreadState_Swap(PyThreadState *); | |
| 202 | 202 | PyAPI_FUNC(PyObject *) PyThreadState_GetDict(void); | |
| 203 | - PyAPI_FUNC(int) PyThreadState_SetAsyncExc(long, PyObject *); | ||
| 203 | + PyAPI_FUNC(int) PyThreadState_SetAsyncExc(unsigned long, PyObject *); | ||
| 204 | 204 | ||
| 205 | 205 | ||
| 206 | 206 | /* Variable and macro for in-line access to current thread state */ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -17,10 +17,14 @@ typedef enum PyLockStatus { | |||
| 17 | 17 | PY_LOCK_INTR | |
| 18 | 18 | } PyLockStatus; | |
| 19 | 19 | ||
| 20 | + #ifndef Py_LIMITED_API | ||
| 21 | + #define PYTHREAD_INVALID_THREAD_ID ((unsigned long)-1) | ||
| 22 | + #endif | ||
| 23 | + | ||
| 20 | 24 | PyAPI_FUNC(void) PyThread_init_thread(void); | |
| 21 | - PyAPI_FUNC(long) PyThread_start_new_thread(void (*)(void *), void *); | ||
| 25 | + PyAPI_FUNC(unsigned long) PyThread_start_new_thread(void (*)(void *), void *); | ||
| 22 | 26 | PyAPI_FUNC(void) PyThread_exit_thread(void); | |
| 23 | - PyAPI_FUNC(long) PyThread_get_thread_ident(void); | ||
| 27 | + PyAPI_FUNC(unsigned long) PyThread_get_thread_ident(void); | ||
| 24 | 28 | ||
| 25 | 29 | PyAPI_FUNC(PyThread_type_lock) PyThread_allocate_lock(void); | |
| 26 | 30 | PyAPI_FUNC(void) PyThread_free_lock(PyThread_type_lock); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -69,7 +69,7 @@ def get_ident(): | |||
| 69 | 69 | available, it is safe to assume that the current process is the | |
| 70 | 70 | only thread. Thus a constant can be safely returned. | |
| 71 | 71 | """ | |
| 72 | - return -1 | ||
| 72 | + return 1 | ||
| 73 | 73 | ||
| 74 | 74 | def allocate_lock(): | |
| 75 | 75 | """Dummy implementation of _thread.allocate_lock().""" | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -111,8 +111,7 @@ def test_exit(self): | |||
| 111 | 111 | def test_ident(self): | |
| 112 | 112 | self.assertIsInstance(_thread.get_ident(), int, | |
| 113 | 113 | "_thread.get_ident() returned a non-integer") | |
| 114 | - self.assertNotEqual(_thread.get_ident(), 0, | ||
| 115 | - "_thread.get_ident() returned 0") | ||
| 114 | + self.assertGreater(_thread.get_ident(), 0) | ||
| 116 | 115 | ||
| 117 | 116 | def test_LockType(self): | |
| 118 | 117 | self.assertIsInstance(_thread.allocate_lock(), _thread.LockType, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -393,6 +393,9 @@ def g456(): | |||
| 393 | 393 | thread_id = thread_info[0] | |
| 394 | 394 | ||
| 395 | 395 | d = sys._current_frames() | |
| 396 | + for tid in d: | ||
| 397 | + self.assertIsInstance(tid, int) | ||
| 398 | + self.assertGreater(tid, 0) | ||
| 396 | 399 | ||
| 397 | 400 | main_id = threading.get_ident() | |
| 398 | 401 | self.assertIn(main_id, d) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -181,6 +181,7 @@ def test_PyThreadState_SetAsyncExc(self): | |||
| 181 | 181 | ctypes = import_module("ctypes") | |
| 182 | 182 | ||
| 183 | 183 | set_async_exc = ctypes.pythonapi.PyThreadState_SetAsyncExc | |
| 184 | + set_async_exc.argtypes = (ctypes.c_ulong, ctypes.py_object) | ||
| 184 | 185 | ||
| 185 | 186 | class AsyncExc(Exception): | |
| 186 | 187 | pass | |
@@ -189,9 +190,11 @@ class AsyncExc(Exception): | |||
| 189 | 190 | ||
| 190 | 191 | # First check it works when setting the exception from the same thread. | |
| 191 | 192 | tid = threading.get_ident() | |
| 193 | + self.assertIsInstance(tid, int) | ||
| 194 | + self.assertGreater(tid, 0) | ||
| 192 | 195 | ||
| 193 | 196 | try: | |
| 194 | - result = set_async_exc(ctypes.c_long(tid), exception) | ||
| 197 | + result = set_async_exc(tid, exception) | ||
| 195 | 198 | # The exception is async, so we might have to keep the VM busy until | |
| 196 | 199 | # it notices. | |
| 197 | 200 | while True: | |
@@ -237,7 +240,7 @@ def run(self): | |||
| 237 | 240 | # Try a thread id that doesn't make sense. | |
| 238 | 241 | if verbose: | |
| 239 | 242 | print(" trying nonsensical thread id") | |
| 240 | - result = set_async_exc(ctypes.c_long(-1), exception) | ||
| 243 | + result = set_async_exc(-1, exception) | ||
| 241 | 244 | self.assertEqual(result, 0) # no thread states modified | |
| 242 | 245 | ||
| 243 | 246 | # Now raise an exception in the worker thread. | |
@@ -250,7 +253,7 @@ def run(self): | |||
| 250 | 253 | self.assertFalse(t.finished) | |
| 251 | 254 | if verbose: | |
| 252 | 255 | print(" attempting to raise asynch exception in worker") | |
| 253 | - result = set_async_exc(ctypes.c_long(t.id), exception) | ||
| 256 | + result = set_async_exc(t.id, exception) | ||
| 254 | 257 | self.assertEqual(result, 1) # one thread state modified | |
| 255 | 258 | if verbose: | |
| 256 | 259 | print(" waiting for worker to say it caught the exception") | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -993,14 +993,14 @@ def _delete(self): | |||
| 993 | 993 | # | |
| 994 | 994 | # Must take care to not raise an exception if _dummy_thread is being | |
| 995 | 995 | # used (and thus this module is being used as an instance of | |
| 996 | - # dummy_threading). _dummy_thread.get_ident() always returns -1 since | ||
| 996 | + # dummy_threading). _dummy_thread.get_ident() always returns 1 since | ||
| 997 | 997 | # there is only one thread if _dummy_thread is being used. Thus | |
| 998 | 998 | # len(_active) is always <= 1 here, and any Thread instance created | |
| 999 | 999 | # overwrites the (if any) thread currently registered in _active. | |
| 1000 | 1000 | # | |
| 1001 | 1001 | # An instance of _MainThread is always created by 'threading'. This | |
| 1002 | 1002 | # gets overwritten the instant an instance of Thread is created; both | |
| 1003 | - # threads return -1 from _dummy_thread.get_ident() and thus have the | ||
| 1003 | + # threads return 1 from _dummy_thread.get_ident() and thus have the | ||
| 1004 | 1004 | # same key in the dict. So when the _MainThread instance created by | |
| 1005 | 1005 | # 'threading' tries to clean itself up when atexit calls this method | |
| 1006 | 1006 | # it gets a KeyError if another Thread instance was created. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -813,6 +813,10 @@ Windows | |||
| 813 | 813 | C API | |
| 814 | 814 | ----- | |
| 815 | 815 | ||
| 816 | + - bpo-6532: The type of results of PyThread_start_new_thread() and | ||
| 817 | + PyThread_get_thread_ident(), and the id parameter of | ||
| 818 | + PyThreadState_SetAsyncExc() changed from "long" to "unsigned long". | ||
| 819 | + | ||
| 816 | 820 | - Issue #27867: Function PySlice_GetIndicesEx() is deprecated and replaced with | |
| 817 | 821 | a macro if Py_LIMITED_API is not set or set to the value between 0x03050400 | |
| 818 | 822 | and 0x03060000 (not including) or 0x03060100 or higher. Added functions | |
| Back | FazBrowse Home | New Git URL |
0 commit comments