deadpool-executor 2025.2.2__tar.gz → 2026.3.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ repos:
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: deadpool-executor
3
- Version: 2025.2.2
3
+ Version: 2026.3.1
4
4
  Summary: Deadpool
5
5
  Author-email: Caleb Hattingh <caleb.hattingh@gmail.com>
6
6
  Description-Content-Type: text/x-rst
@@ -16,7 +16,10 @@ Classifier: Programming Language :: Python :: 3.12
16
16
  Classifier: Programming Language :: Python :: 3.13
17
17
  Classifier: Programming Language :: Python :: Implementation
18
18
  Classifier: Programming Language :: Python :: Implementation :: CPython
19
+ License-File: LICENSE-AGPL
20
+ License-File: LICENSE-Apache
19
21
  Requires-Dist: psutil
22
+ Requires-Dist: setproctitle
20
23
  Requires-Dist: pytest >= 7 ; extra == "test"
21
24
  Requires-Dist: pytest-cov ; extra == "test"
22
25
  Requires-Dist: flake8 ; extra == "test"
@@ -42,8 +42,9 @@ from collections.abc import Mapping
42
42
  from functools import partial
43
43
 
44
44
  import psutil
45
+ from setproctitle import setproctitle
45
46
 
46
- __version__ = "2025.2.2"
47
+ __version__ = "2026.3.1"
47
48
  __all__ = [
48
49
  "Deadpool",
49
50
  "Future",
@@ -641,6 +642,9 @@ class Deadpool(Executor):
641
642
  return fut
642
643
 
643
644
  def shutdown(self, wait: bool = True, *, cancel_futures: bool = False) -> None:
645
+ if self.closed:
646
+ return
647
+
644
648
  logger.debug(f"shutdown: {wait=} {cancel_futures=}")
645
649
 
646
650
  # No more new tasks can be submitted
@@ -705,16 +709,14 @@ class Deadpool(Executor):
705
709
  return self
706
710
 
707
711
  def __exit__(self, exc_type, exc_val, exc_tb):
708
- if not self.closed:
709
- kwargs = {}
710
- if self.shutdown_wait is not None:
711
- kwargs["wait"] = self.shutdown_wait
712
-
713
- if self.shutdown_cancel_futures is not None:
714
- kwargs["cancel_futures"] = self.shutdown_cancel_futures
712
+ kwargs = {}
713
+ if self.shutdown_wait is not None:
714
+ kwargs["wait"] = self.shutdown_wait
715
715
 
716
- self.shutdown(**kwargs)
716
+ if self.shutdown_cancel_futures is not None:
717
+ kwargs["cancel_futures"] = self.shutdown_cancel_futures
717
718
 
719
+ self.shutdown(**kwargs)
718
720
  self.runner_thread.join()
719
721
  return False
720
722
 
@@ -779,6 +781,7 @@ def raw_runner2(
779
781
  mem_clear_threshold_bytes: Optional[int] = None,
780
782
  kill_proc_tree=kill_proc_tree,
781
783
  ):
784
+ setproctitle("deadpool.worker")
782
785
  # This event is used to signal that the "parent"
783
786
  # monitor thread should be deactivated.
784
787
  evt = threading.Event()
@@ -881,7 +884,7 @@ def raw_runner2(
881
884
  f"An exception occurred but pickling it failed. "
882
885
  f"The original exception is presented here as a string with "
883
886
  f"traceback.\n{e}\n{traceback.format_exception(e)}\n\n"
884
- f"The reason for the pickking failure is the following:\n"
887
+ f"The reason for the pickling failure is the following:\n"
885
888
  f"{traceback.format_exception(pickle_error)}"
886
889
  )
887
890
  e = ProcessError(msg)
@@ -9,6 +9,7 @@ dynamic = ["version", "description"]
9
9
  readme = "README.rst"
10
10
  dependencies = [
11
11
  "psutil",
12
+ "setproctitle",
12
13
  ]
13
14
  classifiers = [
14
15
  "License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)",
@@ -344,6 +344,14 @@ def test_shutdown(logging_initializer, wait, cancel_futures):
344
344
  assert result == 123
345
345
 
346
346
 
347
+ @pytest.mark.parametrize("wait", [True, False])
348
+ def test_shutdown_idempotent(wait):
349
+ """Calling shutdown() twice must not deadlock."""
350
+ d = deadpool.Deadpool(max_workers=2)
351
+ d.shutdown(wait=wait)
352
+ d.shutdown(wait=wait)
353
+
354
+
347
355
  @pytest.mark.parametrize("wait", [True, False])
348
356
  @pytest.mark.parametrize("cancel_futures", [True, False])
349
357
  def test_shutdown_manual(logging_initializer, wait, cancel_futures):