deadpool-executor 2025.2.2__tar.gz → 2026.3.2__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.2
4
4
  Summary: Deadpool
5
5
  Author-email: Caleb Hattingh <caleb.hattingh@gmail.com>
6
6
  Description-Content-Type: text/x-rst
@@ -14,9 +14,13 @@ Classifier: Programming Language :: Python :: 3.10
14
14
  Classifier: Programming Language :: Python :: 3.11
15
15
  Classifier: Programming Language :: Python :: 3.12
16
16
  Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
17
18
  Classifier: Programming Language :: Python :: Implementation
18
19
  Classifier: Programming Language :: Python :: Implementation :: CPython
20
+ License-File: LICENSE-AGPL
21
+ License-File: LICENSE-Apache
19
22
  Requires-Dist: psutil
23
+ Requires-Dist: setproctitle
20
24
  Requires-Dist: pytest >= 7 ; extra == "test"
21
25
  Requires-Dist: pytest-cov ; extra == "test"
22
26
  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.2"
47
48
  __all__ = [
48
49
  "Deadpool",
49
50
  "Future",
@@ -571,8 +572,7 @@ class Deadpool(Executor):
571
572
  f"TimeoutError on {worker.pid}, setting ok=False"
572
573
  )
573
574
  worker.ok = False
574
- finally:
575
- break
575
+ break
576
576
  elif not worker.is_alive():
577
577
  self._statistics.tasks_failed.increment()
578
578
  logger.debug(f"p is no longer alive: {worker.process}")
@@ -641,6 +641,9 @@ class Deadpool(Executor):
641
641
  return fut
642
642
 
643
643
  def shutdown(self, wait: bool = True, *, cancel_futures: bool = False) -> None:
644
+ if self.closed:
645
+ return
646
+
644
647
  logger.debug(f"shutdown: {wait=} {cancel_futures=}")
645
648
 
646
649
  # No more new tasks can be submitted
@@ -705,16 +708,14 @@ class Deadpool(Executor):
705
708
  return self
706
709
 
707
710
  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
711
+ kwargs = {}
712
+ if self.shutdown_wait is not None:
713
+ kwargs["wait"] = self.shutdown_wait
715
714
 
716
- self.shutdown(**kwargs)
715
+ if self.shutdown_cancel_futures is not None:
716
+ kwargs["cancel_futures"] = self.shutdown_cancel_futures
717
717
 
718
+ self.shutdown(**kwargs)
718
719
  self.runner_thread.join()
719
720
  return False
720
721
 
@@ -779,6 +780,7 @@ def raw_runner2(
779
780
  mem_clear_threshold_bytes: Optional[int] = None,
780
781
  kill_proc_tree=kill_proc_tree,
781
782
  ):
783
+ setproctitle("deadpool.worker")
782
784
  # This event is used to signal that the "parent"
783
785
  # monitor thread should be deactivated.
784
786
  evt = threading.Event()
@@ -881,7 +883,7 @@ def raw_runner2(
881
883
  f"An exception occurred but pickling it failed. "
882
884
  f"The original exception is presented here as a string with "
883
885
  f"traceback.\n{e}\n{traceback.format_exception(e)}\n\n"
884
- f"The reason for the pickking failure is the following:\n"
886
+ f"The reason for the pickling failure is the following:\n"
885
887
  f"{traceback.format_exception(pickle_error)}"
886
888
  )
887
889
  e = ProcessError(msg)
@@ -10,6 +10,7 @@ import nox
10
10
  "3.11",
11
11
  "3.12",
12
12
  "3.13",
13
+ "3.14",
13
14
  ]
14
15
  )
15
16
  def test(session):
@@ -25,6 +26,7 @@ def test(session):
25
26
  "3.11",
26
27
  "3.12",
27
28
  "3.13",
29
+ "3.14",
28
30
  ]
29
31
  )
30
32
  def testcov(session):
@@ -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+)",
@@ -21,6 +22,7 @@ classifiers = [
21
22
  "Programming Language :: Python :: 3.11",
22
23
  "Programming Language :: Python :: 3.12",
23
24
  "Programming Language :: Python :: 3.13",
25
+ "Programming Language :: Python :: 3.14",
24
26
  "Programming Language :: Python :: Implementation",
25
27
  "Programming Language :: Python :: Implementation :: CPython",
26
28
  ]
@@ -1,6 +1,7 @@
1
1
  import asyncio
2
2
  import logging
3
3
  import os
4
+ import pickle
4
5
  import queue
5
6
  import signal
6
7
  import sys
@@ -344,6 +345,14 @@ def test_shutdown(logging_initializer, wait, cancel_futures):
344
345
  assert result == 123
345
346
 
346
347
 
348
+ @pytest.mark.parametrize("wait", [True, False])
349
+ def test_shutdown_idempotent(wait):
350
+ """Calling shutdown() twice must not deadlock."""
351
+ d = deadpool.Deadpool(max_workers=2)
352
+ d.shutdown(wait=wait)
353
+ d.shutdown(wait=wait)
354
+
355
+
347
356
  @pytest.mark.parametrize("wait", [True, False])
348
357
  @pytest.mark.parametrize("cancel_futures", [True, False])
349
358
  def test_shutdown_manual(logging_initializer, wait, cancel_futures):
@@ -682,7 +691,9 @@ def test_can_pickle_nested_function():
682
691
  with deadpool.Deadpool() as exe:
683
692
  fut = exe.submit(f)
684
693
 
685
- with pytest.raises(AttributeError, match="local object"):
694
+ with pytest.raises(
695
+ (AttributeError, pickle.PicklingError), match="local object"
696
+ ):
686
697
  fut.result()
687
698
 
688
699
 
@@ -696,7 +707,9 @@ def test_can_pickle_nested_function_cf():
696
707
  with ProcessPoolExecutor() as exe:
697
708
  fut = exe.submit(f)
698
709
 
699
- with pytest.raises(AttributeError, match="local object"):
710
+ with pytest.raises(
711
+ (AttributeError, pickle.PicklingError), match="local object"
712
+ ):
700
713
  fut.result()
701
714
 
702
715
 
@@ -706,7 +719,9 @@ def test_can_pickle_lambda_function():
706
719
  with deadpool.Deadpool() as exe:
707
720
  fut = exe.submit(lambda: 123)
708
721
 
709
- with pytest.raises(AttributeError, match="local object"):
722
+ with pytest.raises(
723
+ (AttributeError, pickle.PicklingError), match="local object"
724
+ ):
710
725
  fut.result()
711
726
 
712
727