From 597c6725898705b3b19b96d508379d6bc2acd9c4 Mon Sep 17 00:00:00 2001 From: priyanshu2282-cyber Date: Fri, 16 Jan 2026 02:06:49 +0530 Subject: [PATCH 01/15] socket: fix re-entrant mutation in sendmsg ancillary data --- Modules/socketmodule.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 1ef359cb265ed4..62af80f9ab2262 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -5001,15 +5001,27 @@ _socket_socket_sendmsg_impl(PySocketSockObject *s, PyObject *data_arg, controllen = controllen_last = 0; while (ncmsgbufs < ncmsgs) { size_t bufsize, space; + PyObject *item; - if (!PyArg_Parse(PySequence_Fast_GET_ITEM(cmsg_fast, ncmsgbufs), + item = PySequence_Fast_GET_ITEM(cmsg_fast, ncmsgbufs); + Py_INCREF(item); + + if (!PyArg_Parse(item, "(iiy*):[sendmsg() ancillary data items]", &cmsgs[ncmsgbufs].level, &cmsgs[ncmsgbufs].type, &cmsgs[ncmsgbufs].data)) + Py_DECREF(item); goto finally; + Py_DECREF(item); bufsize = cmsgs[ncmsgbufs++].data.len; - + space=CMSG_SPACE(bufsize); + if(space>maxcmsgslen){ + PyErr_SetString(PyExc_OSError, "ancillary data item too large"); + goto finally; + } + maxcmsgslen+=space; + } #ifdef CMSG_SPACE if (!get_CMSG_SPACE(bufsize, &space)) { #else From 7e57097b1b0827c47726b7f763831ce360cfb5a0 Mon Sep 17 00:00:00 2001 From: priyanshu2282-cyber Date: Fri, 16 Jan 2026 02:07:14 +0530 Subject: [PATCH 02/15] test_socket: add regression test for sendmsg re-entrancy --- Lib/test/test_socket.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 934b7137096bc0..787425edd3d991 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -3572,6 +3572,33 @@ def _testSendmsgAfterClose(self): class SendmsgStreamTests(SendmsgTests): # Tests for sendmsg() which require a stream socket and do not # involve recvmsg() or recvmsg_into(). + @unittest.skipUnless(hasattr(socket.socket, "sendmsg"), + "sendmsg not supported") + def _test_sendmsg_reentrant_ancillary_mutation(self): + import socket + + seq = [] + + class Mut: + def __init__(self): + self.tripped = False + def __index__(self): + if not self.tripped: + self.tripped = True + seq.clear() + return 0 + + seq[:] = [ + (socket.SOL_SOCKET, Mut(), b'x'), + (socket.SOL_SOCKET, 0, b'x'), + ] + + left, right = socket.socketpair() + self.addCleanup(left.close) + self.addCleanup(right.close) + + with self.assertRaises(Exception): + left.sendmsg([b'x'], seq) def testSendmsgExplicitNoneAddr(self): # Check that peer address can be specified as None. From a6fbd4b1889f6312c01f89fc2bd45683db3d14e4 Mon Sep 17 00:00:00 2001 From: priyanshu2282-cyber Date: Fri, 16 Jan 2026 02:42:21 +0530 Subject: [PATCH 03/15] gh-143637: Fix reentrant mutation crash in socket.sendmsg --- Lib/test/test_socket.py | 2 +- Modules/socketmodule.c | 26 +++++++++----------------- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 787425edd3d991..14dd0f6483eeec 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -3596,7 +3596,7 @@ def __index__(self): left, right = socket.socketpair() self.addCleanup(left.close) self.addCleanup(right.close) - + with self.assertRaises(Exception): left.sendmsg([b'x'], seq) diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 62af80f9ab2262..39d4058d998432 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -5007,30 +5007,22 @@ _socket_socket_sendmsg_impl(PySocketSockObject *s, PyObject *data_arg, Py_INCREF(item); if (!PyArg_Parse(item, - "(iiy*):[sendmsg() ancillary data items]", - &cmsgs[ncmsgbufs].level, - &cmsgs[ncmsgbufs].type, - &cmsgs[ncmsgbufs].data)) + "(iiy*):[sendmsg() ancillary data items]", + &cmsgs[ncmsgbufs].level, + &cmsgs[ncmsgbufs].type, + &cmsgs[ncmsgbufs].data)){ Py_DECREF(item); goto finally; + } Py_DECREF(item); + bufsize = cmsgs[ncmsgbufs++].data.len; - space=CMSG_SPACE(bufsize); - if(space>maxcmsgslen){ - PyErr_SetString(PyExc_OSError, "ancillary data item too large"); - goto finally; - } - maxcmsgslen+=space; - } -#ifdef CMSG_SPACE - if (!get_CMSG_SPACE(bufsize, &space)) { -#else - if (!get_CMSG_LEN(bufsize, &space)) { -#endif + + if(!get_CMSG_SPACE(bufsize, &space)){ PyErr_SetString(PyExc_OSError, "ancillary data item too large"); goto finally; } - controllen += space; + controllen+=space; if (controllen > SOCKLEN_T_LIMIT || controllen < controllen_last) { PyErr_SetString(PyExc_OSError, "too much ancillary data"); goto finally; From be7371d2f8ba2bb2c0eae7cbd254db46ba832026 Mon Sep 17 00:00:00 2001 From: priyanshu2282-cyber Date: Fri, 16 Jan 2026 21:59:37 +0530 Subject: [PATCH 04/15] chore: rerun CI From 4703c2b974ff81966ee3e443816a19f83d56e4fd Mon Sep 17 00:00:00 2001 From: priyanshu2282-cyber Date: Sat, 17 Jan 2026 14:06:04 +0530 Subject: [PATCH 05/15] restore spacing style for controllen calculation --- Modules/socketmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 39d4058d998432..952c3a90321c1b 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -5022,7 +5022,7 @@ _socket_socket_sendmsg_impl(PySocketSockObject *s, PyObject *data_arg, PyErr_SetString(PyExc_OSError, "ancillary data item too large"); goto finally; } - controllen+=space; + controllen += space; if (controllen > SOCKLEN_T_LIMIT || controllen < controllen_last) { PyErr_SetString(PyExc_OSError, "too much ancillary data"); goto finally; From 2bd7e14d75e20f5487b2e8a48c484d3c241d862e Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Sat, 17 Jan 2026 08:44:26 +0000 Subject: [PATCH 06/15] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20b?= =?UTF-8?q?lurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2026-01-17-08-44-25.gh-issue-143637.qyPqDo.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2026-01-17-08-44-25.gh-issue-143637.qyPqDo.rst diff --git a/Misc/NEWS.d/next/Library/2026-01-17-08-44-25.gh-issue-143637.qyPqDo.rst b/Misc/NEWS.d/next/Library/2026-01-17-08-44-25.gh-issue-143637.qyPqDo.rst new file mode 100644 index 00000000000000..cbb21194d5b387 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-01-17-08-44-25.gh-issue-143637.qyPqDo.rst @@ -0,0 +1 @@ +Fixed a crash in socket.sendmsg() that could occur if ancillary data is mutated re-entrantly during argument parsing. From 710daaad77fe6e74c5c0633ea2f692d4fd42d53c Mon Sep 17 00:00:00 2001 From: priyanshu2282-cyber Date: Sat, 17 Jan 2026 21:27:32 +0530 Subject: [PATCH 07/15] add public wrapper for sendmsg re-entrant ancillary mutation test --- Lib/test/test_socket.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 14dd0f6483eeec..1cda075e80293c 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -3572,8 +3572,12 @@ def _testSendmsgAfterClose(self): class SendmsgStreamTests(SendmsgTests): # Tests for sendmsg() which require a stream socket and do not # involve recvmsg() or recvmsg_into(). + @unittest.skipUnless(hasattr(socket.socket, "sendmsg"), "sendmsg not supported") + def test_sendmsg_reentrant_ancillary_mutation(self): + self._test_sendmsg_reentrant_ancillary_mutation() + def _test_sendmsg_reentrant_ancillary_mutation(self): import socket From 75d8ae9f74b286bdaf5872b714cc0ea15c96284f Mon Sep 17 00:00:00 2001 From: priyanshu2282-cyber Date: Sat, 17 Jan 2026 21:57:06 +0530 Subject: [PATCH 08/15] fixed trailing whitespace --- Lib/test/test_socket.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 1cda075e80293c..eb208c1a40826b 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -3572,12 +3572,12 @@ def _testSendmsgAfterClose(self): class SendmsgStreamTests(SendmsgTests): # Tests for sendmsg() which require a stream socket and do not # involve recvmsg() or recvmsg_into(). - + @unittest.skipUnless(hasattr(socket.socket, "sendmsg"), "sendmsg not supported") def test_sendmsg_reentrant_ancillary_mutation(self): self._test_sendmsg_reentrant_ancillary_mutation() - + def _test_sendmsg_reentrant_ancillary_mutation(self): import socket From 6f0ddf4bd22b7aa5bbb373610441a8f57c5ba784 Mon Sep 17 00:00:00 2001 From: priyanshu2282-cyber Date: Sun, 18 Jan 2026 00:41:20 +0530 Subject: [PATCH 09/15] PySequence_Tuple instead of PySequence_Fast and removed INCREF, DECREF --- Lib/test/test_socket.py | 10 +++++++--- Modules/socketmodule.c | 15 +++++++-------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index eb208c1a40826b..cb2d66bece5a3f 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -3577,7 +3577,7 @@ class SendmsgStreamTests(SendmsgTests): "sendmsg not supported") def test_sendmsg_reentrant_ancillary_mutation(self): self._test_sendmsg_reentrant_ancillary_mutation() - + def _test_sendmsg_reentrant_ancillary_mutation(self): import socket @@ -3601,8 +3601,12 @@ def __index__(self): self.addCleanup(left.close) self.addCleanup(right.close) - with self.assertRaises(Exception): - left.sendmsg([b'x'], seq) + self.assertRaises( + (TypeError, OSError), + left.sendmsg, + [b'x'], + seq, + ) def testSendmsgExplicitNoneAddr(self): # Check that peer address can be specified as None. diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 952c3a90321c1b..ad93f9a3a0ed5a 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -4977,11 +4977,13 @@ _socket_socket_sendmsg_impl(PySocketSockObject *s, PyObject *data_arg, if (cmsg_arg == NULL) ncmsgs = 0; else { - if ((cmsg_fast = PySequence_Fast(cmsg_arg, - "sendmsg() argument 2 must be an " - "iterable")) == NULL) + cmsg_fast = PySequence_Tuple(cmsg_arg); + if (cmsg_fast == NULL) { + PyErr_SetString(PyExc_TypeError, + "sendmsg() argument 2 must be an iterable"); goto finally; - ncmsgs = PySequence_Fast_GET_SIZE(cmsg_fast); + } + ncmsgs = PyTuple_GET_SIZE(cmsg_fast); } #ifndef CMSG_SPACE @@ -5003,18 +5005,15 @@ _socket_socket_sendmsg_impl(PySocketSockObject *s, PyObject *data_arg, size_t bufsize, space; PyObject *item; - item = PySequence_Fast_GET_ITEM(cmsg_fast, ncmsgbufs); - Py_INCREF(item); + item = PyTuple_GET_ITEM(cmsg_fast, ncmsgbufs); if (!PyArg_Parse(item, "(iiy*):[sendmsg() ancillary data items]", &cmsgs[ncmsgbufs].level, &cmsgs[ncmsgbufs].type, &cmsgs[ncmsgbufs].data)){ - Py_DECREF(item); goto finally; } - Py_DECREF(item); bufsize = cmsgs[ncmsgbufs++].data.len; From ff8af984921d504424d48260e1fb3cedfac6d098 Mon Sep 17 00:00:00 2001 From: priyanshu2282-cyber Date: Sun, 18 Jan 2026 00:57:37 +0530 Subject: [PATCH 10/15] Fix trailing whitespace --- Lib/test/test_socket.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index cb2d66bece5a3f..670066e4603233 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -3577,7 +3577,7 @@ class SendmsgStreamTests(SendmsgTests): "sendmsg not supported") def test_sendmsg_reentrant_ancillary_mutation(self): self._test_sendmsg_reentrant_ancillary_mutation() - + def _test_sendmsg_reentrant_ancillary_mutation(self): import socket From 5f0a05a2f0914e5f637e69af76e9d843ec0ba9e1 Mon Sep 17 00:00:00 2001 From: priyanshu2282-cyber Date: Mon, 19 Jan 2026 10:17:38 +0530 Subject: [PATCH 11/15] Fix sendmsg re-entrant ancillary mutation crash --- Modules/socketmodule.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index ad93f9a3a0ed5a..205affc5d469a6 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -5017,7 +5017,11 @@ _socket_socket_sendmsg_impl(PySocketSockObject *s, PyObject *data_arg, bufsize = cmsgs[ncmsgbufs++].data.len; - if(!get_CMSG_SPACE(bufsize, &space)){ +#ifdef CMSG_SPACE + if (!get_CMSG_SPACE(bufsize, &space)) { +#else + if (!get_CMSG_LEN(bufsize, &space)) { +#endif PyErr_SetString(PyExc_OSError, "ancillary data item too large"); goto finally; } From 082e6b705a7e143c905d3f34b005eef3c0f66b3e Mon Sep 17 00:00:00 2001 From: priyanshu2282-cyber Date: Mon, 19 Jan 2026 21:14:25 +0530 Subject: [PATCH 12/15] Corrected Indentation and moved test to seperate class --- Lib/test/test_socket.py | 61 ++++++++++++++++++----------------------- Modules/socketmodule.c | 14 ++++------ 2 files changed, 32 insertions(+), 43 deletions(-) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 670066e4603233..296927aa6e4029 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -3573,41 +3573,6 @@ class SendmsgStreamTests(SendmsgTests): # Tests for sendmsg() which require a stream socket and do not # involve recvmsg() or recvmsg_into(). - @unittest.skipUnless(hasattr(socket.socket, "sendmsg"), - "sendmsg not supported") - def test_sendmsg_reentrant_ancillary_mutation(self): - self._test_sendmsg_reentrant_ancillary_mutation() - - def _test_sendmsg_reentrant_ancillary_mutation(self): - import socket - - seq = [] - - class Mut: - def __init__(self): - self.tripped = False - def __index__(self): - if not self.tripped: - self.tripped = True - seq.clear() - return 0 - - seq[:] = [ - (socket.SOL_SOCKET, Mut(), b'x'), - (socket.SOL_SOCKET, 0, b'x'), - ] - - left, right = socket.socketpair() - self.addCleanup(left.close) - self.addCleanup(right.close) - - self.assertRaises( - (TypeError, OSError), - left.sendmsg, - [b'x'], - seq, - ) - def testSendmsgExplicitNoneAddr(self): # Check that peer address can be specified as None. self.assertEqual(self.serv_sock.recv(len(MSG)), MSG) @@ -7526,6 +7491,32 @@ def detach(): pass +class SendmsgReentrancyTests(unittest.TestCase): + + @unittest.skipUnless(hasattr(socket.socket, "sendmsg"), + "sendmsg not supported") + def test_sendmsg_reentrant_ancillary_mutation(self): + + class Mut: + def __index__(self): + seq.clear() + return 0 + + seq = [ + (socket.SOL_SOCKET, Mut(), b'x'), + (socket.SOL_SOCKET, 0, b'x'), + ] + + left, right = socket.socketpair() + self.addCleanup(left.close) + self.addCleanup(right.close) + self.assertRaises( + (TypeError, OSError), + left.sendmsg, + [b'x'], + seq, + ) + def setUpModule(): thread_info = threading_helper.threading_setup() unittest.addModuleCleanup(threading_helper.threading_cleanup, *thread_info) diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 205affc5d469a6..bef450308e08d0 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -4982,8 +4982,8 @@ _socket_socket_sendmsg_impl(PySocketSockObject *s, PyObject *data_arg, PyErr_SetString(PyExc_TypeError, "sendmsg() argument 2 must be an iterable"); goto finally; - } - ncmsgs = PyTuple_GET_SIZE(cmsg_fast); + } + ncmsgs = PyTuple_GET_SIZE(cmsg_fast); } #ifndef CMSG_SPACE @@ -5008,13 +5008,11 @@ _socket_socket_sendmsg_impl(PySocketSockObject *s, PyObject *data_arg, item = PyTuple_GET_ITEM(cmsg_fast, ncmsgbufs); if (!PyArg_Parse(item, - "(iiy*):[sendmsg() ancillary data items]", - &cmsgs[ncmsgbufs].level, - &cmsgs[ncmsgbufs].type, - &cmsgs[ncmsgbufs].data)){ + "(iiy*):[sendmsg() ancillary data items]", + &cmsgs[ncmsgbufs].level, + &cmsgs[ncmsgbufs].type, + &cmsgs[ncmsgbufs].data)) goto finally; - } - bufsize = cmsgs[ncmsgbufs++].data.len; #ifdef CMSG_SPACE From fb9912987a8c9ff1cbd62a2471c4281348d47cb1 Mon Sep 17 00:00:00 2001 From: Priyanshu Singh Date: Mon, 19 Jan 2026 21:20:42 +0530 Subject: [PATCH 13/15] Update Modules/socketmodule.c Co-authored-by: Victor Stinner --- Modules/socketmodule.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index bef450308e08d0..c64358fd5be9c1 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -5008,10 +5008,10 @@ _socket_socket_sendmsg_impl(PySocketSockObject *s, PyObject *data_arg, item = PyTuple_GET_ITEM(cmsg_fast, ncmsgbufs); if (!PyArg_Parse(item, - "(iiy*):[sendmsg() ancillary data items]", - &cmsgs[ncmsgbufs].level, - &cmsgs[ncmsgbufs].type, - &cmsgs[ncmsgbufs].data)) + "(iiy*):[sendmsg() ancillary data items]", + &cmsgs[ncmsgbufs].level, + &cmsgs[ncmsgbufs].type, + &cmsgs[ncmsgbufs].data)) goto finally; bufsize = cmsgs[ncmsgbufs++].data.len; From 7ec2dd69bf3619fd7c8cd95faa48bb3538f296fd Mon Sep 17 00:00:00 2001 From: Priyanshu Singh Date: Tue, 20 Jan 2026 17:43:58 +0530 Subject: [PATCH 14/15] Update Modules/socketmodule.c Co-authored-by: Victor Stinner --- Modules/socketmodule.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index c64358fd5be9c1..1ceeb8d7e4925c 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -5003,9 +5003,7 @@ _socket_socket_sendmsg_impl(PySocketSockObject *s, PyObject *data_arg, controllen = controllen_last = 0; while (ncmsgbufs < ncmsgs) { size_t bufsize, space; - PyObject *item; - - item = PyTuple_GET_ITEM(cmsg_fast, ncmsgbufs); + PyObject *item = PyTuple_GET_ITEM(cmsg_fast, ncmsgbufs); if (!PyArg_Parse(item, "(iiy*):[sendmsg() ancillary data items]", From 57b33f1812fe88bf4d28f91f87c39c6829ffec6c Mon Sep 17 00:00:00 2001 From: priyanshu2282-cyber Date: Tue, 20 Jan 2026 18:20:53 +0530 Subject: [PATCH 15/15] Move test to GeneralModuleTests --- Lib/test/test_socket.py | 49 +++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 296927aa6e4029..057fdc76fab4fd 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -913,6 +913,29 @@ def requireSocket(*args): class GeneralModuleTests(unittest.TestCase): + @unittest.skipUnless(hasattr(socket.socket, "sendmsg"),"sendmsg not supported") + def test_sendmsg_reentrant_ancillary_mutation(self): + + class Mut: + def __index__(self): + seq.clear() + return 0 + + seq = [ + (socket.SOL_SOCKET, Mut(), b'x'), + (socket.SOL_SOCKET, 0, b'x'), + ] + + left, right = socket.socketpair() + self.addCleanup(left.close) + self.addCleanup(right.close) + self.assertRaises( + (TypeError, OSError), + left.sendmsg, + [b'x'], + seq, + ) + @unittest.skipUnless(_socket is not None, 'need _socket module') def test_socket_type(self): self.assertTrue(gc.is_tracked(_socket.socket)) @@ -7491,32 +7514,6 @@ def detach(): pass -class SendmsgReentrancyTests(unittest.TestCase): - - @unittest.skipUnless(hasattr(socket.socket, "sendmsg"), - "sendmsg not supported") - def test_sendmsg_reentrant_ancillary_mutation(self): - - class Mut: - def __index__(self): - seq.clear() - return 0 - - seq = [ - (socket.SOL_SOCKET, Mut(), b'x'), - (socket.SOL_SOCKET, 0, b'x'), - ] - - left, right = socket.socketpair() - self.addCleanup(left.close) - self.addCleanup(right.close) - self.assertRaises( - (TypeError, OSError), - left.sendmsg, - [b'x'], - seq, - ) - def setUpModule(): thread_info = threading_helper.threading_setup() unittest.addModuleCleanup(threading_helper.threading_cleanup, *thread_info)