From 7dfa9524a6ca9438448b5fad2f54e9fba26a4444 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Piotr=20Ma=C5=9Blanka?= <piotr.maslanka@henrietta.com.pl>
Date: Sun, 7 Mar 2021 01:50:29 +0100
Subject: [PATCH] added functionality to `ThreadCollection`

---
 CHANGELOG.md                                  |  2 +-
 satella/__init__.py                           |  2 +-
 .../coding/concurrent/thread_collection.py    | 35 +++++++++++++++++++
 3 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 54201402..90b7a918 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,4 +3,4 @@
 * more time-related calls will accept time strings
 * added optional `delay` argument to `call_in_separate_thread`
 * beefed up BogusTerminableThread docs
-* added `ThreadCollection.add`
+* added functionality to `ThreadCollection`
diff --git a/satella/__init__.py b/satella/__init__.py
index e6e7554c..d85f422e 100644
--- a/satella/__init__.py
+++ b/satella/__init__.py
@@ -1 +1 @@
-__version__ = '2.14.47a3'
+__version__ = '2.14.47a4'
diff --git a/satella/coding/concurrent/thread_collection.py b/satella/coding/concurrent/thread_collection.py
index 0867811c..e138022b 100644
--- a/satella/coding/concurrent/thread_collection.py
+++ b/satella/coding/concurrent/thread_collection.py
@@ -1,3 +1,4 @@
+import threading
 import typing as tp
 from threading import Thread
 
@@ -15,10 +16,36 @@ class ThreadCollection:
     >>> tc.start()
     >>> tc.terminate()
     >>> tc.join()
+
+    This also implements iteration (it will return all the threads in the collection) and
+    length check.
     """
 
     __slots__ = ('threads', )
 
+    def __len__(self):
+        return len(self.threads)
+
+    def __iter__(self):
+        return iter(self.threads)
+
+    @classmethod
+    def get_currently_running(cls, include_main_thread: bool = True) -> 'ThreadCollection':
+        """
+        Get all currently running threads as thread collection
+
+        :param include_main_thread: whether to include the main thread
+
+        :return: a thread collection representing all currently running threads
+        """
+        result = []
+        for thread in threading.enumerate():
+            # noinspection PyProtectedMember
+            if not include_main_thread and isinstance(thread, threading._MainThread):
+                continue
+            result.append(thread)
+        return ThreadCollection(result)
+
     @classmethod
     def from_class(cls, cls_to_use, iteratable, **kwargs) -> 'ThreadCollection':
         """
@@ -46,6 +73,14 @@ class ThreadCollection:
     def __init__(self, threads: tp.Sequence[Thread]):
         self.threads = list(threads)
 
+    def append(self, thread: Thread) -> None:
+        """
+        Alias for :meth:`~satella.coding.concurrent.ThreadCollection.add`
+
+        :param thread: thread to add
+        """
+        self.add(thread)
+
     def add(self, thread: Thread) -> None:
         """
         Add a thread to the collection
-- 
GitLab