Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 27 additions & 5 deletions Lib/test/test_threading.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,33 @@ def test_args_argument(self):
t.start()
t.join()

def test_lock_no_args(self):
threading.Lock() # works
self.assertRaises(TypeError, threading.Lock, 1)
self.assertRaises(TypeError, threading.Lock, a=1)
self.assertRaises(TypeError, threading.Lock, 1, 2, a=1, b=2)
def test_args_invalid_arguments_raises_typeerror(self):
def task(x):
pass

invalid_args = (
1,
3.14,
None,
object(),
)

for args in invalid_args:
with self.subTest(args=args):
with self.assertRaises(TypeError):
threading.Thread(target=task, args=args)

def test_args_valid_inputs_does_not_raise(self):
def task():
pass

class CustomIter:
def __iter__(self):
yield
try:
t = threading.Thread(target=task, args=CustomIter())
except TypeError as e:
self.fail(f"Thread raised an exception with an object that has the '__iter__' attribute with error {e}")

def test_lock_no_subclass(self):
# Intentionally disallow subclasses of threading.Lock because they have
Expand Down
2 changes: 2 additions & 0 deletions Lib/threading.py
Original file line number Diff line number Diff line change
Expand Up @@ -909,6 +909,8 @@ class is implemented.

self._target = target
self._name = name
if not hasattr(args, '__iter__'):
raise TypeError(f"'args' must be a iterable like a tuple or list, not {type(args).__name__}")
self._args = args
self._kwargs = kwargs
if daemon is not None:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
threading.Thread now validates that 'args' is iterable. Raises TypeError if it is not.

Loading