Skip to content

Commit 25b2fa5

Browse files
gh-145242: Add early validation for target in Thread and Process
1 parent a9b583d commit 25b2fa5

5 files changed

Lines changed: 21 additions & 2 deletions

File tree

Lib/multiprocessing/process.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,10 @@ def _Popen(self):
7979

8080
def __init__(self, group=None, target=None, name=None, args=(), kwargs=None,
8181
*, daemon=None):
82-
assert group is None, 'group argument must be None for now'
82+
if group is not None:
83+
raise TypeError("group argument must be None for now")
84+
if target is not None and not callable(target):
85+
raise TypeError("target must be callable")
8386
count = next(_process_counter)
8487
self._identity = _current_process._identity + (count,)
8588
self._config = _current_process._config.copy()

Lib/test/_test_multiprocessing.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,12 @@ def test_current(self):
326326
self.assertEqual(current.ident, os.getpid())
327327
self.assertEqual(current.exitcode, None)
328328

329+
def test_invalid_args(self):
330+
with self.assertRaisesRegex(TypeError, "group argument must be None"):
331+
self.Process(group="not None")
332+
with self.assertRaisesRegex(TypeError, "target must be callable"):
333+
self.Process(target=123)
334+
329335
@warnings_helper.ignore_fork_in_thread_deprecation_warnings()
330336
def test_set_executable(self):
331337
if self.TYPE == 'threads':

Lib/test/test_threading.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,12 @@ def func(): pass
151151
thread = threading.Thread(target=func)
152152
self.assertEqual(thread.name, "Thread-5 (func)")
153153

154+
def test_invalid_args(self):
155+
with self.assertRaisesRegex(TypeError, "group argument must be None"):
156+
threading.Thread(group="not None")
157+
with self.assertRaisesRegex(TypeError, "target must be callable"):
158+
threading.Thread(target=123)
159+
154160
def test_args_argument(self):
155161
# bpo-45735: Using list or tuple as *args* in constructor could
156162
# achieve the same effect.

Lib/threading.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -901,7 +901,10 @@ class is implemented.
901901
else to the thread.
902902
903903
"""
904-
assert group is None, "group argument must be None for now"
904+
if group is not None:
905+
raise TypeError("group argument must be None for now")
906+
if target is not None and not callable(target):
907+
raise TypeError("target must be callable")
905908
if kwargs is None:
906909
kwargs = {}
907910
if name:
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added early validation of the ``target`` argument in :class:`threading.Thread` and :class:`multiprocessing.Process` constructors. If ``target`` is not callable, a :exc:`TypeError` is now raised immediately in the calling thread, resulting in a clearer traceback. Optimized the validation of the reserved ``group`` argument by replacing internal assertions with :exc:`TypeError`.

0 commit comments

Comments
 (0)