From b6231da6b4494519cf5da320356ca2a16b3dc389 Mon Sep 17 00:00:00 2001 From: CharlieZhao Date: Thu, 27 Jan 2022 10:34:39 +0800 Subject: [PATCH 01/15] Change arguments description in `Thread`. --- Doc/library/threading.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 8c7664328a49df..c0582ea129c2c4 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -314,7 +314,7 @@ since it is impossible to detect the termination of alien threads. or "Thread-*N* (target)" where "target" is ``target.__name__`` if the *target* argument is specified. - *args* is the argument tuple for the target invocation. Defaults to ``()``. + *args* is a list or tuple of arguments for the target invocation. Defaults to ``()``. *kwargs* is a dictionary of keyword arguments for the target invocation. Defaults to ``{}``. From 76f8d90ce562d6fc77a4491281d4e5c1cc256d46 Mon Sep 17 00:00:00 2001 From: CharlieZhao Date: Thu, 27 Jan 2022 11:39:29 +0800 Subject: [PATCH 02/15] Add doc example to use list or tuple as *args* --- Lib/threading.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Lib/threading.py b/Lib/threading.py index 6068d06ab6c906..2e29da05c47c99 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -852,7 +852,7 @@ class is implemented. *name* is the thread name. By default, a unique name is constructed of the form "Thread-N" where N is a small decimal number. - *args* is the argument tuple for the target invocation. Defaults to (). + *args* is a list or tuple of arguments for the target invocation. Defaults to (). *kwargs* is a dictionary of keyword arguments for the target invocation. Defaults to {}. @@ -861,6 +861,19 @@ class is implemented. the base class constructor (Thread.__init__()) before doing anything else to the thread. + Example to use list or tuple as *args* in constructor: + + >>> from threading import Thread + >>> def func_print(arg1, arg2): + ... print(arg1, arg2) + >>> Thread(target=func_print, args=[1, 2]).run() + 1 2 + >>> Thread(target=func_print, args=["str1", "str2"]).run() + str1 str2 + >>> Thread(target=func_print, args=(1, 2,)).run() + 1 2 + >>> Thread(target=func_print, args=("str1", "str2",)).run() + str1 str2 """ assert group is None, "group argument must be None for now" if kwargs is None: From d30897ce17cf6569acd338feaec07593619dc843 Mon Sep 17 00:00:00 2001 From: CharlieZhao Date: Thu, 27 Jan 2022 12:34:36 +0800 Subject: [PATCH 03/15] Add test cases in `Thread` for checking the validity of list *args*. --- Lib/test/test_threading.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index 4830571474b5bf..33a3d24479a2b2 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -123,6 +123,30 @@ def func(): pass thread = threading.Thread(target=func) self.assertEqual(thread.name, "Thread-5 (func)") + def test_run_with_list_args(self): + """ + Using list or tuple as *args* in constructor could achieve the same effect. + """ + num_list = [1, 2] + + def func_with_num_args(arg1, arg2): + self.assertEqual(arg1, num_list[0]) + self.assertEqual(arg2, num_list[1]) + + str_list = ["str1", "str2"] + + def func_with_str_args(arg1, arg2): + self.assertEqual(arg1, str_list[0]) + self.assertEqual(arg2, str_list[1]) + + test_suits = [ + [num_list, func_with_num_args], + [str_list, func_with_str_args], + ] + for test_case in test_suits: + t = threading.Thread(target=test_case[1], args=test_case[0]) + t.start() + @cpython_only def test_disallow_instantiation(self): # Ensure that the type disallows instantiation (bpo-43916) From b1abac7fea73b1f24f4dbbbe44d7ca0376bb6e6b Mon Sep 17 00:00:00 2001 From: CharlieZhao Date: Thu, 27 Jan 2022 16:52:08 +0800 Subject: [PATCH 04/15] Add test cases to check tuple *args*. --- Lib/test/test_threading.py | 40 +++++++++++++++++++++++++------------- Lib/threading.py | 16 ++++++--------- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index 33a3d24479a2b2..bf021ae3a7785e 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -123,27 +123,39 @@ def func(): pass thread = threading.Thread(target=func) self.assertEqual(thread.name, "Thread-5 (func)") - def test_run_with_list_args(self): - """ - Using list or tuple as *args* in constructor could achieve the same effect. - """ - num_list = [1, 2] + def test_run_with_diff_args(self): + # Using list or tuple as *args* in constructor could + # achieve the same effect. + num_list = [1] + num_tuple = (1,) + + def func_with_num_args(arg): + self.assertEqual(arg, 1) + + str_list = ["str"] + str_tuple = ("str",) + + def func_with_str_args(arg): + self.assertEqual(arg, "str") - def func_with_num_args(arg1, arg2): - self.assertEqual(arg1, num_list[0]) - self.assertEqual(arg2, num_list[1]) + list_in_tuple = ([1],) + tuple_in_list = [(1,)] - str_list = ["str1", "str2"] + def func_with_list_args(arg): + self.assertEqual(arg, [1]) - def func_with_str_args(arg1, arg2): - self.assertEqual(arg1, str_list[0]) - self.assertEqual(arg2, str_list[1]) + def func_with_tuple_args(arg): + self.assertEqual(arg, (1,)) - test_suits = [ + test_cases = [ [num_list, func_with_num_args], + [num_tuple, func_with_num_args], [str_list, func_with_str_args], + [str_tuple, func_with_str_args], + [list_in_tuple, func_with_list_args], + [tuple_in_list, func_with_tuple_args] ] - for test_case in test_suits: + for test_case in test_cases: t = threading.Thread(target=test_case[1], args=test_case[0]) t.start() diff --git a/Lib/threading.py b/Lib/threading.py index 2e29da05c47c99..7b2514232467b6 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -864,16 +864,12 @@ class is implemented. Example to use list or tuple as *args* in constructor: >>> from threading import Thread - >>> def func_print(arg1, arg2): - ... print(arg1, arg2) - >>> Thread(target=func_print, args=[1, 2]).run() - 1 2 - >>> Thread(target=func_print, args=["str1", "str2"]).run() - str1 str2 - >>> Thread(target=func_print, args=(1, 2,)).run() - 1 2 - >>> Thread(target=func_print, args=("str1", "str2",)).run() - str1 str2 + >>> t = Thread(target=print, args=[1]) + >>> t.run() + 1 + >>> t = Thread(target=print, args=(1,)) + >>> t.run() + 1 """ assert group is None, "group argument must be None for now" if kwargs is None: From 6580a8bcb9c05943399a698e85b75cc476b925e1 Mon Sep 17 00:00:00 2001 From: CharlieZhao Date: Fri, 28 Jan 2022 10:08:47 +0800 Subject: [PATCH 05/15] Remove import statement in doc example. --- Lib/threading.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Lib/threading.py b/Lib/threading.py index 7b2514232467b6..a217cbb6b46f41 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -861,9 +861,8 @@ class is implemented. the base class constructor (Thread.__init__()) before doing anything else to the thread. - Example to use list or tuple as *args* in constructor: + Example of using this constructor with a list or tuple *args*: - >>> from threading import Thread >>> t = Thread(target=print, args=[1]) >>> t.run() 1 From c973169fa64b4ae92e50dcc22876a9e8b389d998 Mon Sep 17 00:00:00 2001 From: CharlieZhao Date: Fri, 28 Jan 2022 15:26:26 +0800 Subject: [PATCH 06/15] Add doc example to threading.rst. --- Doc/library/threading.rst | 13 +++++++++++++ Lib/test/test_threading.py | 26 +++++++------------------- Lib/threading.py | 8 -------- 3 files changed, 20 insertions(+), 27 deletions(-) diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index c0582ea129c2c4..2bcb72b6d4e50a 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -353,6 +353,19 @@ since it is impossible to detect the termination of alien threads. the *target* argument, if any, with positional and keyword arguments taken from the *args* and *kwargs* arguments, respectively. + Using list or tuple as the *args* argument which passed to the :class:`Thread` + could achieve the same effect. + + Example:: + + >>> from threading import Thread + >>> t = Thread(target=print, args=[1]) + >>> t.run() + 1 + >>> t = Thread(target=print, args=(1,)) + >>> t.run() + 1 + .. method:: join(timeout=None) Wait until the thread terminates. This blocks the calling thread until diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index bf021ae3a7785e..dc01af5bd221f7 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -123,37 +123,25 @@ def func(): pass thread = threading.Thread(target=func) self.assertEqual(thread.name, "Thread-5 (func)") - def test_run_with_diff_args(self): + def test_args_argument(self): # Using list or tuple as *args* in constructor could # achieve the same effect. num_list = [1] num_tuple = (1,) - def func_with_num_args(arg): - self.assertEqual(arg, 1) - str_list = ["str"] str_tuple = ("str",) - def func_with_str_args(arg): - self.assertEqual(arg, "str") - list_in_tuple = ([1],) tuple_in_list = [(1,)] - def func_with_list_args(arg): - self.assertEqual(arg, [1]) - - def func_with_tuple_args(arg): - self.assertEqual(arg, (1,)) - test_cases = [ - [num_list, func_with_num_args], - [num_tuple, func_with_num_args], - [str_list, func_with_str_args], - [str_tuple, func_with_str_args], - [list_in_tuple, func_with_list_args], - [tuple_in_list, func_with_tuple_args] + [num_list, lambda arg: self.assertEqual(arg, 1)], + [num_tuple, lambda arg: self.assertEqual(arg, 1)], + [str_list, lambda arg: self.assertEqual(arg, "str")], + [str_tuple, lambda arg: self.assertEqual(arg, "str")], + [list_in_tuple, lambda arg: self.assertEqual(arg, [1])], + [tuple_in_list, lambda arg: self.assertEqual(arg, (1,))] ] for test_case in test_cases: t = threading.Thread(target=test_case[1], args=test_case[0]) diff --git a/Lib/threading.py b/Lib/threading.py index a217cbb6b46f41..642f93e1eec31c 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -861,14 +861,6 @@ class is implemented. the base class constructor (Thread.__init__()) before doing anything else to the thread. - Example of using this constructor with a list or tuple *args*: - - >>> t = Thread(target=print, args=[1]) - >>> t.run() - 1 - >>> t = Thread(target=print, args=(1,)) - >>> t.run() - 1 """ assert group is None, "group argument must be None for now" if kwargs is None: From 29393db6000dd548f955ee4157f6418e199130b4 Mon Sep 17 00:00:00 2001 From: CharlieZhao Date: Sat, 29 Jan 2022 10:53:23 +0800 Subject: [PATCH 07/15] Add doc example and test cases for `multiprocessing.Process`. --- Doc/library/multiprocessing.rst | 17 ++++++++++++++++- Lib/test/_test_multiprocessing.py | 24 ++++++++++++++++++++++++ Lib/test/test_threading.py | 2 +- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index 9bb7dd3d703ab1..75441841a632d6 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -485,7 +485,9 @@ The :mod:`multiprocessing` package mostly replicates the API of the to ``True`` or ``False``. If ``None`` (the default), this flag will be inherited from the creating process. - By default, no arguments are passed to *target*. + By default, no arguments are passed to *target*, the *args* is set to ``()``. + Besides, similar to :class:`threading.Thread`, it is feasible to use a list or + tuple as the *args* to pass arguments. If a subclass overrides the constructor, it must make sure it invokes the base class constructor (:meth:`Process.__init__`) before doing anything else @@ -503,6 +505,19 @@ The :mod:`multiprocessing` package mostly replicates the API of the the target argument, if any, with sequential and keyword arguments taken from the *args* and *kwargs* arguments, respectively. + Using list or tuple as the *args* argument which passed to the :class:`Process` + could achieve the same effect. + + Example:: + + >>> from multiprocessing import Process + >>> p = Process(target=print, args=[1]) + >>> p.run() + 1 + >>> p = Process(target=print, args=(1,)) + >>> p.run() + 1 + .. method:: start() Start the process's activity. diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index b2d656ab428975..c2475413593d8c 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -247,6 +247,30 @@ def test_current(self): self.assertEqual(current.ident, os.getpid()) self.assertEqual(current.exitcode, None) + def test_args_argument(self): + # bpo-45735: Using list or tuple as *args* in constructor could + # achieve the same effect. + num_list = [1] + num_tuple = (1,) + + str_list = ["str"] + str_tuple = ("str",) + + list_in_tuple = ([1],) + tuple_in_list = [(1,)] + + test_cases = [ + [num_list, lambda arg: self.assertEqual(arg, 1)], + [num_tuple, lambda arg: self.assertEqual(arg, 1)], + [str_list, lambda arg: self.assertEqual(arg, "str")], + [str_tuple, lambda arg: self.assertEqual(arg, "str")], + [list_in_tuple, lambda arg: self.assertEqual(arg, [1])], + [tuple_in_list, lambda arg: self.assertEqual(arg, (1,))] + ] + for test_case in test_cases: + p = multiprocessing.Process(target=test_case[1], args=test_case[0]) + p.start() + def test_daemon_argument(self): if self.TYPE == "threads": self.skipTest('test not appropriate for {}'.format(self.TYPE)) diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index dc01af5bd221f7..b31cc1cc33d835 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -124,7 +124,7 @@ def func(): pass self.assertEqual(thread.name, "Thread-5 (func)") def test_args_argument(self): - # Using list or tuple as *args* in constructor could + # bpo-45735: Using list or tuple as *args* in constructor could # achieve the same effect. num_list = [1] num_tuple = (1,) From 7c5e3ca4d3cb24412c3d19b4384c7a7ceba16263 Mon Sep 17 00:00:00 2001 From: CharlieZhao Date: Sat, 29 Jan 2022 11:00:38 +0800 Subject: [PATCH 08/15] Add ACKS entry. --- Misc/ACKS | 1 + 1 file changed, 1 insertion(+) diff --git a/Misc/ACKS b/Misc/ACKS index cf023c9af927ab..f943217e59b4e9 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1999,6 +1999,7 @@ Yuxiao Zeng Uwe Zessin Cheng Zhang George Zhang +Charlie Zhao Kai Zhu Tarek Ziadé Jelle Zijlstra From 1390ba5e86b7d909472e8a49d48e91e4b8edad8b Mon Sep 17 00:00:00 2001 From: CharlieZhao Date: Sat, 29 Jan 2022 11:34:27 +0800 Subject: [PATCH 09/15] Fix test case in `Process`. --- Lib/test/_test_multiprocessing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index c2475413593d8c..8bce6d8cf18da7 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -268,7 +268,7 @@ def test_args_argument(self): [tuple_in_list, lambda arg: self.assertEqual(arg, (1,))] ] for test_case in test_cases: - p = multiprocessing.Process(target=test_case[1], args=test_case[0]) + p = self.Process(target=test_case[1], args=test_case[0]) p.start() def test_daemon_argument(self): From d6413808ffbf6161dc12bb7e04ae4227ead706ff Mon Sep 17 00:00:00 2001 From: Charlie Zhao <68189100+CharlieZhao95@users.noreply.github.com> Date: Sat, 29 Jan 2022 14:17:11 +0800 Subject: [PATCH 10/15] Update Doc/library/multiprocessing.rst Cleaner English here. Co-authored-by: Tim Peters --- Doc/library/multiprocessing.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index 75441841a632d6..eb8d1714bb325a 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -505,8 +505,8 @@ The :mod:`multiprocessing` package mostly replicates the API of the the target argument, if any, with sequential and keyword arguments taken from the *args* and *kwargs* arguments, respectively. - Using list or tuple as the *args* argument which passed to the :class:`Process` - could achieve the same effect. + Using a list or tuple as the *args* argument passed to :class:`Process` + achieves the same effect. Example:: From 547652d093ae5f5e4e5e5d45e1e4a22dcd6daf9b Mon Sep 17 00:00:00 2001 From: Charlie Zhao <68189100+CharlieZhao95@users.noreply.github.com> Date: Sat, 29 Jan 2022 14:20:58 +0800 Subject: [PATCH 11/15] Update Doc/library/multiprocessing.rst Cleaner English to describe *args*. Co-authored-by: Tim Peters --- Doc/library/multiprocessing.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index eb8d1714bb325a..c5a5398b4df500 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -485,9 +485,9 @@ The :mod:`multiprocessing` package mostly replicates the API of the to ``True`` or ``False``. If ``None`` (the default), this flag will be inherited from the creating process. - By default, no arguments are passed to *target*, the *args* is set to ``()``. - Besides, similar to :class:`threading.Thread`, it is feasible to use a list or - tuple as the *args* to pass arguments. + By default, no arguments are passed to *target*. The *args* argument, + which defaults to ``()``, can be used to specify a list or tuple of the arguments + to pass to *target*. If a subclass overrides the constructor, it must make sure it invokes the base class constructor (:meth:`Process.__init__`) before doing anything else From 702b41929ac698b0bcd2c7de732e4b685ac6d489 Mon Sep 17 00:00:00 2001 From: CharlieZhao Date: Sat, 29 Jan 2022 17:01:04 +0800 Subject: [PATCH 12/15] Use `with self.subTest(...)`. --- Lib/test/_test_multiprocessing.py | 5 +++-- Lib/test/test_threading.py | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 8bce6d8cf18da7..16c878a971fd97 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -268,8 +268,9 @@ def test_args_argument(self): [tuple_in_list, lambda arg: self.assertEqual(arg, (1,))] ] for test_case in test_cases: - p = self.Process(target=test_case[1], args=test_case[0]) - p.start() + with self.subTest(test_case=test_case): + p = self.Process(target=test_case[1], args=test_case[0]) + p.start() def test_daemon_argument(self): if self.TYPE == "threads": diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index b31cc1cc33d835..8bf9870f9d4b80 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -144,8 +144,9 @@ def test_args_argument(self): [tuple_in_list, lambda arg: self.assertEqual(arg, (1,))] ] for test_case in test_cases: - t = threading.Thread(target=test_case[1], args=test_case[0]) - t.start() + with self.subTest(test_case=test_case): + t = threading.Thread(target=test_case[1], args=test_case[0]) + t.start() @cpython_only def test_disallow_instantiation(self): From 00ac9d3b47bd48ace2d57dc30ec2178f9b2f2940 Mon Sep 17 00:00:00 2001 From: CharlieZhao Date: Sun, 30 Jan 2022 10:11:48 +0800 Subject: [PATCH 13/15] Replace `lambda` with `_test()`. --- Lib/test/_test_multiprocessing.py | 32 ++++++++++++------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 16c878a971fd97..763d62a32494fd 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -250,27 +250,19 @@ def test_current(self): def test_args_argument(self): # bpo-45735: Using list or tuple as *args* in constructor could # achieve the same effect. - num_list = [1] - num_tuple = (1,) - - str_list = ["str"] - str_tuple = ("str",) - - list_in_tuple = ([1],) - tuple_in_list = [(1,)] - - test_cases = [ - [num_list, lambda arg: self.assertEqual(arg, 1)], - [num_tuple, lambda arg: self.assertEqual(arg, 1)], - [str_list, lambda arg: self.assertEqual(arg, "str")], - [str_tuple, lambda arg: self.assertEqual(arg, "str")], - [list_in_tuple, lambda arg: self.assertEqual(arg, [1])], - [tuple_in_list, lambda arg: self.assertEqual(arg, (1,))] - ] + test_cases = [1, "str", [1], (1,)] + for test_case in test_cases: - with self.subTest(test_case=test_case): - p = self.Process(target=test_case[1], args=test_case[0]) - p.start() + for args_type in [list, tuple]: + with self.subTest(test_case=test_case, args_type=args_type): + q = self.Queue(1) + # pass a tuple or list as args + args = args_type([q, test_case]) + p = self.Process(target=self._test, args=args) + p.start() + child_recv_args = q.get() + self.assertEqual(child_recv_args[0], test_case) + p.join() def test_daemon_argument(self): if self.TYPE == "threads": From 3efdc5fded64831ffaaa2322dcc75ce21ec5a61a Mon Sep 17 00:00:00 2001 From: CharlieZhao Date: Sun, 30 Jan 2022 11:46:54 +0800 Subject: [PATCH 14/15] Replace `list` with `tuple` in the test_cases and make loop more readable. --- Lib/test/_test_multiprocessing.py | 33 +++++++++++++++++++------------ Lib/test/test_threading.py | 23 ++++++++++----------- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 763d62a32494fd..6b1b1677910d18 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -250,19 +250,26 @@ def test_current(self): def test_args_argument(self): # bpo-45735: Using list or tuple as *args* in constructor could # achieve the same effect. - test_cases = [1, "str", [1], (1,)] - - for test_case in test_cases: - for args_type in [list, tuple]: - with self.subTest(test_case=test_case, args_type=args_type): - q = self.Queue(1) - # pass a tuple or list as args - args = args_type([q, test_case]) - p = self.Process(target=self._test, args=args) - p.start() - child_recv_args = q.get() - self.assertEqual(child_recv_args[0], test_case) - p.join() + args_cases = (1, "str", [1], (1,)) + args_types = (list, tuple) + + test_cases = itertools.product(args_cases, args_types) + + for args, args_type in test_cases: + with self.subTest(args=args, args_type=args_type): + q = self.Queue(1) + # pass a tuple or list as args + p = self.Process(target=self._test_args, args=args_type((q, args))) + p.daemon = True + p.start() + child_args = q.get() + self.assertEqual(child_args, args) + p.join() + close_queue(q) + + @classmethod + def _test_args(cls, q, arg): + q.put(arg) def test_daemon_argument(self): if self.TYPE == "threads": diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index 8bf9870f9d4b80..16c6934c6d432b 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -135,17 +135,18 @@ def test_args_argument(self): list_in_tuple = ([1],) tuple_in_list = [(1,)] - test_cases = [ - [num_list, lambda arg: self.assertEqual(arg, 1)], - [num_tuple, lambda arg: self.assertEqual(arg, 1)], - [str_list, lambda arg: self.assertEqual(arg, "str")], - [str_tuple, lambda arg: self.assertEqual(arg, "str")], - [list_in_tuple, lambda arg: self.assertEqual(arg, [1])], - [tuple_in_list, lambda arg: self.assertEqual(arg, (1,))] - ] - for test_case in test_cases: - with self.subTest(test_case=test_case): - t = threading.Thread(target=test_case[1], args=test_case[0]) + test_cases = ( + (num_list, lambda arg: self.assertEqual(arg, 1)), + (num_tuple, lambda arg: self.assertEqual(arg, 1)), + (str_list, lambda arg: self.assertEqual(arg, "str")), + (str_tuple, lambda arg: self.assertEqual(arg, "str")), + (list_in_tuple, lambda arg: self.assertEqual(arg, [1])), + (tuple_in_list, lambda arg: self.assertEqual(arg, (1,))) + ) + + for args, target in test_cases: + with self.subTest(target=target, args=args): + t = threading.Thread(target=target, args=args) t.start() @cpython_only From 8384a45d79b4f53cb6b5f546550231638ab78dbd Mon Sep 17 00:00:00 2001 From: CharlieZhao Date: Fri, 11 Feb 2022 14:48:25 +0800 Subject: [PATCH 15/15] Remove redundant spaces. --- Doc/library/multiprocessing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index c5a5398b4df500..1cd1ec6f1b20e6 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -486,7 +486,7 @@ The :mod:`multiprocessing` package mostly replicates the API of the inherited from the creating process. By default, no arguments are passed to *target*. The *args* argument, - which defaults to ``()``, can be used to specify a list or tuple of the arguments + which defaults to ``()``, can be used to specify a list or tuple of the arguments to pass to *target*. If a subclass overrides the constructor, it must make sure it invokes the