executorlib 0.0.10__tar.gz → 0.0.11__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.
Files changed (68) hide show
  1. {executorlib-0.0.10/executorlib.egg-info → executorlib-0.0.11}/PKG-INFO +3 -3
  2. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/_version.py +3 -3
  3. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/backend/cache_parallel.py +1 -5
  4. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/backend/interactive_parallel.py +8 -8
  5. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/backend/interactive_serial.py +10 -10
  6. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/base/executor.py +16 -9
  7. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/cache/queue_spawner.py +5 -3
  8. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/cache/shared.py +6 -11
  9. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/cache/subprocess_spawner.py +4 -5
  10. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/interactive/create.py +17 -9
  11. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/interactive/executor.py +4 -2
  12. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/interactive/shared.py +30 -26
  13. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/interactive/slurm.py +3 -3
  14. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/standalone/hdf.py +4 -4
  15. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/standalone/inputcheck.py +8 -9
  16. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/standalone/interactive/backend.py +1 -1
  17. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/standalone/interactive/communication.py +3 -3
  18. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/standalone/interactive/spawner.py +4 -1
  19. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/standalone/plot.py +3 -3
  20. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/standalone/queue.py +1 -1
  21. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/standalone/serialize.py +12 -3
  22. {executorlib-0.0.10 → executorlib-0.0.11/executorlib.egg-info}/PKG-INFO +3 -3
  23. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib.egg-info/requires.txt +2 -2
  24. {executorlib-0.0.10 → executorlib-0.0.11}/pyproject.toml +37 -2
  25. {executorlib-0.0.10 → executorlib-0.0.11}/LICENSE +0 -0
  26. {executorlib-0.0.10 → executorlib-0.0.11}/MANIFEST.in +0 -0
  27. {executorlib-0.0.10 → executorlib-0.0.11}/README.md +0 -0
  28. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/__init__.py +0 -0
  29. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/backend/__init__.py +0 -0
  30. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/backend/cache_serial.py +0 -0
  31. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/base/__init__.py +0 -0
  32. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/cache/__init__.py +0 -0
  33. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/cache/backend.py +0 -0
  34. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/cache/executor.py +0 -0
  35. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/interactive/__init__.py +0 -0
  36. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/interactive/flux.py +0 -0
  37. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/standalone/__init__.py +0 -0
  38. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/standalone/command.py +0 -0
  39. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/standalone/interactive/__init__.py +0 -0
  40. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib/standalone/thread.py +0 -0
  41. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib.egg-info/SOURCES.txt +0 -0
  42. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib.egg-info/dependency_links.txt +0 -0
  43. {executorlib-0.0.10 → executorlib-0.0.11}/executorlib.egg-info/top_level.txt +0 -0
  44. {executorlib-0.0.10 → executorlib-0.0.11}/setup.cfg +0 -0
  45. {executorlib-0.0.10 → executorlib-0.0.11}/setup.py +0 -0
  46. {executorlib-0.0.10 → executorlib-0.0.11}/tests/test_backend_serial.py +0 -0
  47. {executorlib-0.0.10 → executorlib-0.0.11}/tests/test_cache_executor_interactive.py +0 -0
  48. {executorlib-0.0.10 → executorlib-0.0.11}/tests/test_cache_executor_mpi.py +0 -0
  49. {executorlib-0.0.10 → executorlib-0.0.11}/tests/test_cache_executor_pysqa_flux.py +0 -0
  50. {executorlib-0.0.10 → executorlib-0.0.11}/tests/test_cache_executor_serial.py +0 -0
  51. {executorlib-0.0.10 → executorlib-0.0.11}/tests/test_cache_hdf.py +0 -0
  52. {executorlib-0.0.10 → executorlib-0.0.11}/tests/test_cache_shared.py +0 -0
  53. {executorlib-0.0.10 → executorlib-0.0.11}/tests/test_dependencies_executor.py +0 -0
  54. {executorlib-0.0.10 → executorlib-0.0.11}/tests/test_executor_backend_flux.py +0 -0
  55. {executorlib-0.0.10 → executorlib-0.0.11}/tests/test_executor_backend_mpi.py +0 -0
  56. {executorlib-0.0.10 → executorlib-0.0.11}/tests/test_executor_backend_mpi_noblock.py +0 -0
  57. {executorlib-0.0.10 → executorlib-0.0.11}/tests/test_flux_executor.py +0 -0
  58. {executorlib-0.0.10 → executorlib-0.0.11}/tests/test_integration_pyiron_workflow.py +0 -0
  59. {executorlib-0.0.10 → executorlib-0.0.11}/tests/test_local_executor.py +0 -0
  60. {executorlib-0.0.10 → executorlib-0.0.11}/tests/test_local_executor_future.py +0 -0
  61. {executorlib-0.0.10 → executorlib-0.0.11}/tests/test_pysqa_subprocess.py +0 -0
  62. {executorlib-0.0.10 → executorlib-0.0.11}/tests/test_shared_backend.py +0 -0
  63. {executorlib-0.0.10 → executorlib-0.0.11}/tests/test_shared_communication.py +0 -0
  64. {executorlib-0.0.10 → executorlib-0.0.11}/tests/test_shared_executorbase.py +0 -0
  65. {executorlib-0.0.10 → executorlib-0.0.11}/tests/test_shared_input_check.py +0 -0
  66. {executorlib-0.0.10 → executorlib-0.0.11}/tests/test_shared_thread.py +0 -0
  67. {executorlib-0.0.10 → executorlib-0.0.11}/tests/test_shell_executor.py +0 -0
  68. {executorlib-0.0.10 → executorlib-0.0.11}/tests/test_shell_interactive.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: executorlib
3
- Version: 0.0.10
3
+ Version: 0.0.11
4
4
  Summary: Scale serial and MPI-parallel python functions over hundreds of compute nodes all from within a jupyter notebook or serial python process.
5
5
  Author-email: Jan Janssen <janssen@lanl.gov>
6
6
  License: BSD 3-Clause License
@@ -60,7 +60,7 @@ Requires-Dist: networkx<=3.4.2,>=2.8.8; extra == "graph"
60
60
  Provides-Extra: graphnotebook
61
61
  Requires-Dist: pygraphviz<=1.14,>=1.10; extra == "graphnotebook"
62
62
  Requires-Dist: networkx<=3.4.2,>=2.8.8; extra == "graphnotebook"
63
- Requires-Dist: ipython<=8.31.0,>=7.33.0; extra == "graphnotebook"
63
+ Requires-Dist: ipython<=8.32.0,>=7.33.0; extra == "graphnotebook"
64
64
  Provides-Extra: mpi
65
65
  Requires-Dist: mpi4py<=4.0.1,>=3.1.4; extra == "mpi"
66
66
  Provides-Extra: submission
@@ -72,7 +72,7 @@ Requires-Dist: pysqa==0.2.3; extra == "all"
72
72
  Requires-Dist: h5py<=3.12.1,>=3.6.0; extra == "all"
73
73
  Requires-Dist: pygraphviz<=1.14,>=1.10; extra == "all"
74
74
  Requires-Dist: networkx<=3.4.2,>=2.8.8; extra == "all"
75
- Requires-Dist: ipython<=8.31.0,>=7.33.0; extra == "all"
75
+ Requires-Dist: ipython<=8.32.0,>=7.33.0; extra == "all"
76
76
 
77
77
  # executorlib
78
78
  [![Unittests](https://github.com/pyiron/executorlib/actions/workflows/unittest-openmpi.yml/badge.svg)](https://github.com/pyiron/executorlib/actions/workflows/unittest-openmpi.yml)
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2025-02-01T14:41:16+0100",
11
+ "date": "2025-02-03T20:15:36+0100",
12
12
  "dirty": true,
13
13
  "error": null,
14
- "full-revisionid": "2a5c109632ab691cd7e4309ca43a29354424b091",
15
- "version": "0.0.10"
14
+ "full-revisionid": "11d44cc6f9a0f096fb8b95e72c6b28f3b1994146",
15
+ "version": "0.0.11"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -1,7 +1,6 @@
1
1
  import pickle
2
2
  import sys
3
3
  import time
4
- from typing import Any
5
4
 
6
5
  import cloudpickle
7
6
 
@@ -40,10 +39,7 @@ def main() -> None:
40
39
  apply_dict = backend_load_file(file_name=file_name)
41
40
  apply_dict = MPI.COMM_WORLD.bcast(apply_dict, root=0)
42
41
  output = apply_dict["fn"].__call__(*apply_dict["args"], **apply_dict["kwargs"])
43
- if mpi_size_larger_one:
44
- result = MPI.COMM_WORLD.gather(output, root=0)
45
- else:
46
- result = output
42
+ result = MPI.COMM_WORLD.gather(output, root=0) if mpi_size_larger_one else output
47
43
  if mpi_rank_zero:
48
44
  backend_write_file(
49
45
  file_name=file_name,
@@ -57,17 +57,17 @@ def main() -> None:
57
57
  input_dict = MPI.COMM_WORLD.bcast(input_dict, root=0)
58
58
 
59
59
  # Parse input
60
- if "shutdown" in input_dict.keys() and input_dict["shutdown"]:
60
+ if "shutdown" in input_dict and input_dict["shutdown"]:
61
61
  if mpi_rank_zero:
62
62
  interface_send(socket=socket, result_dict={"result": True})
63
63
  interface_shutdown(socket=socket, context=context)
64
64
  MPI.COMM_WORLD.Barrier()
65
65
  break
66
66
  elif (
67
- "fn" in input_dict.keys()
68
- and "init" not in input_dict.keys()
69
- and "args" in input_dict.keys()
70
- and "kwargs" in input_dict.keys()
67
+ "fn" in input_dict
68
+ and "init" not in input_dict
69
+ and "args" in input_dict
70
+ and "kwargs" in input_dict
71
71
  ):
72
72
  # Execute function
73
73
  try:
@@ -87,10 +87,10 @@ def main() -> None:
87
87
  if mpi_rank_zero:
88
88
  interface_send(socket=socket, result_dict={"result": output_reply})
89
89
  elif (
90
- "init" in input_dict.keys()
90
+ "init" in input_dict
91
91
  and input_dict["init"]
92
- and "args" in input_dict.keys()
93
- and "kwargs" in input_dict.keys()
92
+ and "args" in input_dict
93
+ and "kwargs" in input_dict
94
94
  ):
95
95
  memory = call_funct(input_dict=input_dict, funct=None)
96
96
 
@@ -1,6 +1,6 @@
1
1
  import sys
2
2
  from os.path import abspath
3
- from typing import List, Optional
3
+ from typing import Optional
4
4
 
5
5
  from executorlib.standalone.interactive.backend import call_funct, parse_arguments
6
6
  from executorlib.standalone.interactive.communication import (
@@ -11,7 +11,7 @@ from executorlib.standalone.interactive.communication import (
11
11
  )
12
12
 
13
13
 
14
- def main(argument_lst: Optional[List[str]] = None):
14
+ def main(argument_lst: Optional[list[str]] = None):
15
15
  """
16
16
  The main function of the program.
17
17
 
@@ -40,15 +40,15 @@ def main(argument_lst: Optional[List[str]] = None):
40
40
  input_dict = interface_receive(socket=socket)
41
41
 
42
42
  # Parse input
43
- if "shutdown" in input_dict.keys() and input_dict["shutdown"]:
43
+ if "shutdown" in input_dict and input_dict["shutdown"]:
44
44
  interface_send(socket=socket, result_dict={"result": True})
45
45
  interface_shutdown(socket=socket, context=context)
46
46
  break
47
47
  elif (
48
- "fn" in input_dict.keys()
49
- and "init" not in input_dict.keys()
50
- and "args" in input_dict.keys()
51
- and "kwargs" in input_dict.keys()
48
+ "fn" in input_dict
49
+ and "init" not in input_dict
50
+ and "args" in input_dict
51
+ and "kwargs" in input_dict
52
52
  ):
53
53
  # Execute function
54
54
  try:
@@ -62,10 +62,10 @@ def main(argument_lst: Optional[List[str]] = None):
62
62
  # Send output
63
63
  interface_send(socket=socket, result_dict={"result": output})
64
64
  elif (
65
- "init" in input_dict.keys()
65
+ "init" in input_dict
66
66
  and input_dict["init"]
67
- and "args" in input_dict.keys()
68
- and "kwargs" in input_dict.keys()
67
+ and "args" in input_dict
68
+ and "kwargs" in input_dict
69
69
  ):
70
70
  memory = call_funct(input_dict=input_dict, funct=None)
71
71
 
@@ -1,3 +1,4 @@
1
+ import contextlib
1
2
  import queue
2
3
  from concurrent.futures import (
3
4
  Executor as FutureExecutor,
@@ -5,7 +6,7 @@ from concurrent.futures import (
5
6
  from concurrent.futures import (
6
7
  Future,
7
8
  )
8
- from typing import Callable, List, Optional, Union
9
+ from typing import Callable, Optional, Union
9
10
 
10
11
  from executorlib.standalone.inputcheck import check_resource_dict
11
12
  from executorlib.standalone.queue import cancel_items_in_queue
@@ -28,7 +29,7 @@ class ExecutorBase(FutureExecutor):
28
29
  cloudpickle_register(ind=3)
29
30
  self._max_cores = max_cores
30
31
  self._future_queue: Optional[queue.Queue] = queue.Queue()
31
- self._process: Optional[Union[RaisingThread, List[RaisingThread]]] = None
32
+ self._process: Optional[Union[RaisingThread, list[RaisingThread]]] = None
32
33
 
33
34
  @property
34
35
  def info(self) -> Optional[dict]:
@@ -40,13 +41,13 @@ class ExecutorBase(FutureExecutor):
40
41
  """
41
42
  if self._process is not None and isinstance(self._process, list):
42
43
  meta_data_dict = self._process[0].get_kwargs().copy()
43
- if "future_queue" in meta_data_dict.keys():
44
+ if "future_queue" in meta_data_dict:
44
45
  del meta_data_dict["future_queue"]
45
46
  meta_data_dict["max_workers"] = len(self._process)
46
47
  return meta_data_dict
47
48
  elif self._process is not None:
48
49
  meta_data_dict = self._process.get_kwargs().copy()
49
- if "future_queue" in meta_data_dict.keys():
50
+ if "future_queue" in meta_data_dict:
50
51
  del meta_data_dict["future_queue"]
51
52
  return meta_data_dict
52
53
  else:
@@ -62,7 +63,13 @@ class ExecutorBase(FutureExecutor):
62
63
  """
63
64
  return self._future_queue
64
65
 
65
- def submit(self, fn: Callable, *args, resource_dict: dict = {}, **kwargs) -> Future: # type: ignore
66
+ def submit( # type: ignore
67
+ self,
68
+ fn: Callable,
69
+ *args,
70
+ resource_dict: Optional[dict] = None,
71
+ **kwargs,
72
+ ) -> Future:
66
73
  """
67
74
  Submits a callable to be executed with the given arguments.
68
75
 
@@ -87,7 +94,9 @@ class ExecutorBase(FutureExecutor):
87
94
  Returns:
88
95
  Future: A Future representing the given call.
89
96
  """
90
- cores = resource_dict.get("cores", None)
97
+ if resource_dict is None:
98
+ resource_dict = {}
99
+ cores = resource_dict.get("cores")
91
100
  if (
92
101
  cores is not None
93
102
  and self._max_cores is not None
@@ -161,7 +170,5 @@ class ExecutorBase(FutureExecutor):
161
170
  """
162
171
  Clean-up the resources associated with the Executor.
163
172
  """
164
- try:
173
+ with contextlib.suppress(AttributeError, RuntimeError):
165
174
  self.shutdown(wait=False)
166
- except (AttributeError, RuntimeError):
167
- pass
@@ -1,6 +1,6 @@
1
1
  import os
2
2
  import subprocess
3
- from typing import List, Optional, Tuple, Union
3
+ from typing import Optional, Union
4
4
 
5
5
  from pysqa import QueueAdapter
6
6
 
@@ -10,7 +10,7 @@ from executorlib.standalone.inputcheck import check_file_exists
10
10
 
11
11
  def execute_with_pysqa(
12
12
  command: list,
13
- task_dependent_lst: list[int] = [],
13
+ task_dependent_lst: Optional[list[int]] = None,
14
14
  file_name: Optional[str] = None,
15
15
  resource_dict: Optional[dict] = None,
16
16
  config_directory: Optional[str] = None,
@@ -35,6 +35,8 @@ def execute_with_pysqa(
35
35
  Returns:
36
36
  int: queuing system ID
37
37
  """
38
+ if task_dependent_lst is None:
39
+ task_dependent_lst = []
38
40
  check_file_exists(file_name=file_name)
39
41
  queue_id = get_queue_id(file_name=file_name)
40
42
  qa = QueueAdapter(
@@ -79,7 +81,7 @@ def _pysqa_execute_command(
79
81
  split_output: bool = True,
80
82
  shell: bool = False,
81
83
  error_filename: str = "pysqa.err",
82
- ) -> Union[str, List[str]]:
84
+ ) -> Union[str, list[str]]:
83
85
  """
84
86
  A wrapper around the subprocess.check_output function. Modified from pysqa to raise an exception if the subprocess
85
87
  fails to submit the job to the queue.
@@ -1,9 +1,10 @@
1
+ import contextlib
1
2
  import importlib.util
2
3
  import os
3
4
  import queue
4
5
  import sys
5
6
  from concurrent.futures import Future
6
- from typing import Any, Callable, Optional, Tuple
7
+ from typing import Any, Callable, Optional
7
8
 
8
9
  from executorlib.standalone.command import get_command_path
9
10
  from executorlib.standalone.hdf import dump, get_output
@@ -79,15 +80,9 @@ def execute_tasks_h5(
79
80
  file_name_dict: dict = {}
80
81
  while True:
81
82
  task_dict = None
82
- try:
83
+ with contextlib.suppress(queue.Empty):
83
84
  task_dict = future_queue.get_nowait()
84
- except queue.Empty:
85
- pass
86
- if (
87
- task_dict is not None
88
- and "shutdown" in task_dict.keys()
89
- and task_dict["shutdown"]
90
- ):
85
+ if task_dict is not None and "shutdown" in task_dict and task_dict["shutdown"]:
91
86
  if terminate_function is not None:
92
87
  for task in process_dict.values():
93
88
  terminate_function(task=task)
@@ -110,7 +105,7 @@ def execute_tasks_h5(
110
105
  fn_kwargs=task_kwargs,
111
106
  resource_dict=task_resource_dict,
112
107
  )
113
- if task_key not in memory_dict.keys():
108
+ if task_key not in memory_dict:
114
109
  if task_key + ".h5out" not in os.listdir(cache_directory):
115
110
  file_name = os.path.join(cache_directory, task_key + ".h5in")
116
111
  dump(file_name=file_name, data_dict=data_dict)
@@ -204,7 +199,7 @@ def _check_task_output(
204
199
 
205
200
  def _convert_args_and_kwargs(
206
201
  task_dict: dict, memory_dict: dict, file_name_dict: dict
207
- ) -> Tuple[list, dict, list]:
202
+ ) -> tuple[list, dict, list]:
208
203
  """
209
204
  Convert the arguments and keyword arguments in a task dictionary to the appropriate types.
210
205
 
@@ -7,7 +7,7 @@ from executorlib.standalone.inputcheck import check_file_exists
7
7
 
8
8
  def execute_in_subprocess(
9
9
  command: list,
10
- task_dependent_lst: list = [],
10
+ task_dependent_lst: Optional[list] = None,
11
11
  file_name: Optional[str] = None,
12
12
  resource_dict: Optional[dict] = None,
13
13
  config_directory: Optional[str] = None,
@@ -33,6 +33,8 @@ def execute_in_subprocess(
33
33
  subprocess.Popen: The subprocess object.
34
34
 
35
35
  """
36
+ if task_dependent_lst is None:
37
+ task_dependent_lst = []
36
38
  check_file_exists(file_name=file_name)
37
39
  while len(task_dependent_lst) > 0:
38
40
  task_dependent_lst = [
@@ -46,10 +48,7 @@ def execute_in_subprocess(
46
48
  raise ValueError("backend parameter is not supported for subprocess spawner.")
47
49
  if resource_dict is None:
48
50
  resource_dict = {}
49
- if "cwd" in resource_dict:
50
- cwd = resource_dict["cwd"]
51
- else:
52
- cwd = cache_directory
51
+ cwd = resource_dict.get("cwd", cache_directory)
53
52
  return subprocess.Popen(command, universal_newlines=True, cwd=cwd)
54
53
 
55
54
 
@@ -35,7 +35,7 @@ def create_executor(
35
35
  backend: str = "local",
36
36
  max_cores: Optional[int] = None,
37
37
  cache_directory: Optional[str] = None,
38
- resource_dict: dict = {},
38
+ resource_dict: Optional[dict] = None,
39
39
  flux_executor=None,
40
40
  flux_executor_pmi_mode: Optional[str] = None,
41
41
  flux_executor_nesting: bool = False,
@@ -83,6 +83,8 @@ def create_executor(
83
83
  of the individual function.
84
84
  init_function (None): optional function to preset arguments for functions which are submitted later
85
85
  """
86
+ if resource_dict is None:
87
+ resource_dict = {}
86
88
  if flux_executor is not None and backend != "flux_allocation":
87
89
  backend = "flux_allocation"
88
90
  if backend == "flux_allocation":
@@ -149,7 +151,7 @@ def create_flux_allocation_executor(
149
151
  max_workers: Optional[int] = None,
150
152
  max_cores: Optional[int] = None,
151
153
  cache_directory: Optional[str] = None,
152
- resource_dict: dict = {},
154
+ resource_dict: Optional[dict] = None,
153
155
  flux_executor=None,
154
156
  flux_executor_pmi_mode: Optional[str] = None,
155
157
  flux_executor_nesting: bool = False,
@@ -160,6 +162,8 @@ def create_flux_allocation_executor(
160
162
  ) -> Union[InteractiveStepExecutor, InteractiveExecutor]:
161
163
  check_init_function(block_allocation=block_allocation, init_function=init_function)
162
164
  check_pmi(backend="flux_allocation", pmi=flux_executor_pmi_mode)
165
+ if resource_dict is None:
166
+ resource_dict = {}
163
167
  cores_per_worker = resource_dict.get("cores", 1)
164
168
  resource_dict["cache_directory"] = cache_directory
165
169
  resource_dict["hostname_localhost"] = hostname_localhost
@@ -167,9 +171,9 @@ def create_flux_allocation_executor(
167
171
  check_command_line_argument_lst(
168
172
  command_line_argument_lst=resource_dict.get("slurm_cmd_args", [])
169
173
  )
170
- if "openmpi_oversubscribe" in resource_dict.keys():
174
+ if "openmpi_oversubscribe" in resource_dict:
171
175
  del resource_dict["openmpi_oversubscribe"]
172
- if "slurm_cmd_args" in resource_dict.keys():
176
+ if "slurm_cmd_args" in resource_dict:
173
177
  del resource_dict["slurm_cmd_args"]
174
178
  resource_dict["flux_executor"] = flux_executor
175
179
  resource_dict["flux_executor_pmi_mode"] = flux_executor_pmi_mode
@@ -206,12 +210,14 @@ def create_slurm_allocation_executor(
206
210
  max_workers: Optional[int] = None,
207
211
  max_cores: Optional[int] = None,
208
212
  cache_directory: Optional[str] = None,
209
- resource_dict: dict = {},
213
+ resource_dict: Optional[dict] = None,
210
214
  hostname_localhost: Optional[bool] = None,
211
215
  block_allocation: bool = False,
212
216
  init_function: Optional[Callable] = None,
213
217
  ) -> Union[InteractiveStepExecutor, InteractiveExecutor]:
214
218
  check_init_function(block_allocation=block_allocation, init_function=init_function)
219
+ if resource_dict is None:
220
+ resource_dict = {}
215
221
  cores_per_worker = resource_dict.get("cores", 1)
216
222
  resource_dict["cache_directory"] = cache_directory
217
223
  resource_dict["hostname_localhost"] = hostname_localhost
@@ -246,12 +252,14 @@ def create_local_executor(
246
252
  max_workers: Optional[int] = None,
247
253
  max_cores: Optional[int] = None,
248
254
  cache_directory: Optional[str] = None,
249
- resource_dict: dict = {},
255
+ resource_dict: Optional[dict] = None,
250
256
  hostname_localhost: Optional[bool] = None,
251
257
  block_allocation: bool = False,
252
258
  init_function: Optional[Callable] = None,
253
259
  ) -> Union[InteractiveStepExecutor, InteractiveExecutor]:
254
260
  check_init_function(block_allocation=block_allocation, init_function=init_function)
261
+ if resource_dict is None:
262
+ resource_dict = {}
255
263
  cores_per_worker = resource_dict.get("cores", 1)
256
264
  resource_dict["cache_directory"] = cache_directory
257
265
  resource_dict["hostname_localhost"] = hostname_localhost
@@ -260,11 +268,11 @@ def create_local_executor(
260
268
  check_command_line_argument_lst(
261
269
  command_line_argument_lst=resource_dict.get("slurm_cmd_args", [])
262
270
  )
263
- if "threads_per_core" in resource_dict.keys():
271
+ if "threads_per_core" in resource_dict:
264
272
  del resource_dict["threads_per_core"]
265
- if "gpus_per_core" in resource_dict.keys():
273
+ if "gpus_per_core" in resource_dict:
266
274
  del resource_dict["gpus_per_core"]
267
- if "slurm_cmd_args" in resource_dict.keys():
275
+ if "slurm_cmd_args" in resource_dict:
268
276
  del resource_dict["slurm_cmd_args"]
269
277
  if block_allocation:
270
278
  resource_dict["init_function"] = init_function
@@ -1,5 +1,5 @@
1
1
  from concurrent.futures import Future
2
- from typing import Any, Callable, Dict, Optional
2
+ from typing import Any, Callable, Optional
3
3
 
4
4
  from executorlib.base.executor import ExecutorBase
5
5
  from executorlib.interactive.shared import execute_tasks_with_dependencies
@@ -64,7 +64,7 @@ class ExecutorWithDependencies(ExecutorBase):
64
64
  self,
65
65
  fn: Callable[..., Any],
66
66
  *args: Any,
67
- resource_dict: Dict[str, Any] = {},
67
+ resource_dict: Optional[dict[str, Any]] = None,
68
68
  **kwargs: Any,
69
69
  ) -> Future:
70
70
  """
@@ -80,6 +80,8 @@ class ExecutorWithDependencies(ExecutorBase):
80
80
  Future: A future object representing the result of the task.
81
81
 
82
82
  """
83
+ if resource_dict is None:
84
+ resource_dict = {}
83
85
  if not self._generate_dependency_graph:
84
86
  f = super().submit(fn, *args, resource_dict=resource_dict, **kwargs)
85
87
  else:
@@ -5,7 +5,7 @@ import sys
5
5
  import time
6
6
  from concurrent.futures import Future
7
7
  from time import sleep
8
- from typing import Any, Callable, List, Optional, Tuple, Union
8
+ from typing import Any, Callable, Optional, Union
9
9
 
10
10
  from executorlib.base.executor import ExecutorBase, cancel_items_in_queue
11
11
  from executorlib.standalone.command import get_command_path
@@ -23,7 +23,9 @@ from executorlib.standalone.thread import RaisingThread
23
23
 
24
24
 
25
25
  class ExecutorBroker(ExecutorBase):
26
- def submit(self, fn: Callable, *args, resource_dict: dict = {}, **kwargs) -> Future: # type: ignore
26
+ def submit( # type: ignore
27
+ self, fn: Callable, *args, resource_dict: Optional[dict] = None, **kwargs
28
+ ) -> Future:
27
29
  """
28
30
  Submits a callable to be executed with the given arguments.
29
31
 
@@ -48,6 +50,8 @@ class ExecutorBroker(ExecutorBase):
48
50
  Returns:
49
51
  Future: A Future representing the given call.
50
52
  """
53
+ if resource_dict is None:
54
+ resource_dict = {}
51
55
  check_resource_dict_is_empty(resource_dict=resource_dict)
52
56
  check_resource_dict(function=fn)
53
57
  f: Future = Future()
@@ -84,7 +88,7 @@ class ExecutorBroker(ExecutorBase):
84
88
  self._process = None
85
89
  self._future_queue = None
86
90
 
87
- def _set_process(self, process: List[RaisingThread]): # type: ignore
91
+ def _set_process(self, process: list[RaisingThread]): # type: ignore
88
92
  """
89
93
  Set the process for the executor.
90
94
 
@@ -112,7 +116,7 @@ class InteractiveExecutor(ExecutorBroker):
112
116
  Examples:
113
117
 
114
118
  >>> import numpy as np
115
- >>> from executorlib.interactive.executor import InteractiveExecutor
119
+ >>> from executorlib.interactive.shared import InteractiveExecutor
116
120
  >>>
117
121
  >>> def calc(i, j, k):
118
122
  >>> from mpi4py import MPI
@@ -133,10 +137,12 @@ class InteractiveExecutor(ExecutorBroker):
133
137
  def __init__(
134
138
  self,
135
139
  max_workers: int = 1,
136
- executor_kwargs: dict = {},
140
+ executor_kwargs: Optional[dict] = None,
137
141
  spawner: type[BaseSpawner] = MpiExecSpawner,
138
142
  ):
139
- super().__init__(max_cores=executor_kwargs.get("max_cores", None))
143
+ if executor_kwargs is None:
144
+ executor_kwargs = {}
145
+ super().__init__(max_cores=executor_kwargs.get("max_cores"))
140
146
  executor_kwargs["future_queue"] = self._future_queue
141
147
  executor_kwargs["spawner"] = spawner
142
148
  executor_kwargs["queue_join_on_shutdown"] = False
@@ -167,7 +173,7 @@ class InteractiveStepExecutor(ExecutorBase):
167
173
  Examples:
168
174
 
169
175
  >>> import numpy as np
170
- >>> from executorlib.interactive.executor import InteractiveStepExecutor
176
+ >>> from executorlib.interactive.shared import InteractiveStepExecutor
171
177
  >>>
172
178
  >>> def calc(i, j, k):
173
179
  >>> from mpi4py import MPI
@@ -175,7 +181,7 @@ class InteractiveStepExecutor(ExecutorBase):
175
181
  >>> rank = MPI.COMM_WORLD.Get_rank()
176
182
  >>> return np.array([i, j, k]), size, rank
177
183
  >>>
178
- >>> with PyFluxStepExecutor(max_cores=2) as p:
184
+ >>> with InteractiveStepExecutor(max_cores=2) as p:
179
185
  >>> fs = p.submit(calc, 2, j=4, k=3, resource_dict={"cores": 2})
180
186
  >>> print(fs.result())
181
187
 
@@ -187,10 +193,12 @@ class InteractiveStepExecutor(ExecutorBase):
187
193
  self,
188
194
  max_cores: Optional[int] = None,
189
195
  max_workers: Optional[int] = None,
190
- executor_kwargs: dict = {},
196
+ executor_kwargs: Optional[dict] = None,
191
197
  spawner: type[BaseSpawner] = MpiExecSpawner,
192
198
  ):
193
- super().__init__(max_cores=executor_kwargs.get("max_cores", None))
199
+ if executor_kwargs is None:
200
+ executor_kwargs = {}
201
+ super().__init__(max_cores=executor_kwargs.get("max_cores"))
194
202
  executor_kwargs["future_queue"] = self._future_queue
195
203
  executor_kwargs["spawner"] = spawner
196
204
  executor_kwargs["max_cores"] = max_cores
@@ -244,13 +252,13 @@ def execute_parallel_tasks(
244
252
  )
245
253
  while True:
246
254
  task_dict = future_queue.get()
247
- if "shutdown" in task_dict.keys() and task_dict["shutdown"]:
255
+ if "shutdown" in task_dict and task_dict["shutdown"]:
248
256
  interface.shutdown(wait=task_dict["wait"])
249
257
  future_queue.task_done()
250
258
  if queue_join_on_shutdown:
251
259
  future_queue.join()
252
260
  break
253
- elif "fn" in task_dict.keys() and "future" in task_dict.keys():
261
+ elif "fn" in task_dict and "future" in task_dict:
254
262
  if cache_directory is None:
255
263
  _execute_task(
256
264
  interface=interface, task_dict=task_dict, future_queue=future_queue
@@ -293,17 +301,17 @@ def execute_separate_tasks(
293
301
  active_task_dict: dict = {}
294
302
  process_lst: list = []
295
303
  qtask_lst: list = []
296
- if "cores" not in kwargs.keys():
304
+ if "cores" not in kwargs:
297
305
  kwargs["cores"] = 1
298
306
  while True:
299
307
  task_dict = future_queue.get()
300
- if "shutdown" in task_dict.keys() and task_dict["shutdown"]:
308
+ if "shutdown" in task_dict and task_dict["shutdown"]:
301
309
  if task_dict["wait"]:
302
310
  _ = [process.join() for process in process_lst]
303
311
  future_queue.task_done()
304
312
  future_queue.join()
305
313
  break
306
- elif "fn" in task_dict.keys() and "future" in task_dict.keys():
314
+ elif "fn" in task_dict and "future" in task_dict:
307
315
  qtask: queue.Queue = queue.Queue()
308
316
  process, active_task_dict = _submit_function_to_separate_process(
309
317
  task_dict=task_dict,
@@ -343,18 +351,14 @@ def execute_tasks_with_dependencies(
343
351
  except queue.Empty:
344
352
  task_dict = None
345
353
  if ( # shutdown the executor
346
- task_dict is not None
347
- and "shutdown" in task_dict.keys()
348
- and task_dict["shutdown"]
354
+ task_dict is not None and "shutdown" in task_dict and task_dict["shutdown"]
349
355
  ):
350
356
  executor.shutdown(wait=task_dict["wait"])
351
357
  future_queue.task_done()
352
358
  future_queue.join()
353
359
  break
354
360
  elif ( # handle function submitted to the executor
355
- task_dict is not None
356
- and "fn" in task_dict.keys()
357
- and "future" in task_dict.keys()
361
+ task_dict is not None and "fn" in task_dict and "future" in task_dict
358
362
  ):
359
363
  future_lst, ready_flag = _get_future_objects_from_input(task_dict=task_dict)
360
364
  if len(future_lst) == 0 or ready_flag:
@@ -438,7 +442,7 @@ def _wait_for_free_slots(
438
442
  return active_task_dict
439
443
 
440
444
 
441
- def _submit_waiting_task(wait_lst: List[dict], executor_queue: queue.Queue) -> list:
445
+ def _submit_waiting_task(wait_lst: list[dict], executor_queue: queue.Queue) -> list:
442
446
  """
443
447
  Submit the waiting tasks, which future inputs have been completed, to the executor
444
448
 
@@ -451,7 +455,7 @@ def _submit_waiting_task(wait_lst: List[dict], executor_queue: queue.Queue) -> l
451
455
  """
452
456
  wait_tmp_lst = []
453
457
  for task_wait_dict in wait_lst:
454
- if all([future.done() for future in task_wait_dict["future_lst"]]):
458
+ if all(future.done() for future in task_wait_dict["future_lst"]):
455
459
  del task_wait_dict["future_lst"]
456
460
  task_wait_dict["args"], task_wait_dict["kwargs"] = _update_futures_in_input(
457
461
  args=task_wait_dict["args"], kwargs=task_wait_dict["kwargs"]
@@ -462,7 +466,7 @@ def _submit_waiting_task(wait_lst: List[dict], executor_queue: queue.Queue) -> l
462
466
  return wait_tmp_lst
463
467
 
464
468
 
465
- def _update_futures_in_input(args: tuple, kwargs: dict) -> Tuple[tuple, dict]:
469
+ def _update_futures_in_input(args: tuple, kwargs: dict) -> tuple[tuple, dict]:
466
470
  """
467
471
  Evaluate future objects in the arguments and keyword arguments by calling future.result()
468
472
 
@@ -474,7 +478,7 @@ def _update_futures_in_input(args: tuple, kwargs: dict) -> Tuple[tuple, dict]:
474
478
  tuple, dict: arguments and keyword arguments with each future object in them being evaluated
475
479
  """
476
480
 
477
- def get_result(arg: Union[List[Future], Future]) -> Any:
481
+ def get_result(arg: Union[list[Future], Future]) -> Any:
478
482
  if isinstance(arg, Future):
479
483
  return arg.result()
480
484
  elif isinstance(arg, list):
@@ -552,7 +556,7 @@ def _submit_function_to_separate_process(
552
556
  resource_dict = task_dict.pop("resource_dict").copy()
553
557
  qtask.put(task_dict)
554
558
  qtask.put({"shutdown": True, "wait": True})
555
- if "cores" not in resource_dict.keys() or (
559
+ if "cores" not in resource_dict or (
556
560
  resource_dict["cores"] == 1 and executor_kwargs["cores"] >= 1
557
561
  ):
558
562
  resource_dict["cores"] = executor_kwargs["cores"]
@@ -28,7 +28,7 @@ class SrunSpawner(SubprocessSpawner):
28
28
  threads_per_core: int = 1,
29
29
  gpus_per_core: int = 0,
30
30
  openmpi_oversubscribe: bool = False,
31
- slurm_cmd_args: list[str] = [],
31
+ slurm_cmd_args: Optional[list[str]] = None,
32
32
  ):
33
33
  """
34
34
  Srun interface implementation.
@@ -79,7 +79,7 @@ def generate_slurm_command(
79
79
  threads_per_core: int = 1,
80
80
  gpus_per_core: int = 0,
81
81
  openmpi_oversubscribe: bool = False,
82
- slurm_cmd_args: list[str] = [],
82
+ slurm_cmd_args: Optional[list[str]] = None,
83
83
  ) -> list[str]:
84
84
  """
85
85
  Generate the command list for the SLURM interface.
@@ -104,6 +104,6 @@ def generate_slurm_command(
104
104
  command_prepend_lst += ["--gpus-per-task=" + str(gpus_per_core)]
105
105
  if openmpi_oversubscribe:
106
106
  command_prepend_lst += ["--oversubscribe"]
107
- if len(slurm_cmd_args) > 0:
107
+ if slurm_cmd_args is not None and len(slurm_cmd_args) > 0:
108
108
  command_prepend_lst += slurm_cmd_args
109
109
  return command_prepend_lst
@@ -1,5 +1,5 @@
1
1
  import os
2
- from typing import Any, List, Optional, Tuple
2
+ from typing import Any, Optional
3
3
 
4
4
  import cloudpickle
5
5
  import h5py
@@ -26,7 +26,7 @@ def dump(file_name: Optional[str], data_dict: dict) -> None:
26
26
  if file_name is not None:
27
27
  with h5py.File(file_name, "a") as fname:
28
28
  for data_key, data_value in data_dict.items():
29
- if data_key in group_dict.keys():
29
+ if data_key in group_dict:
30
30
  fname.create_dataset(
31
31
  name="/" + group_dict[data_key],
32
32
  data=np.void(cloudpickle.dumps(data_value)),
@@ -60,7 +60,7 @@ def load(file_name: str) -> dict:
60
60
  return data_dict
61
61
 
62
62
 
63
- def get_output(file_name: str) -> Tuple[bool, Any]:
63
+ def get_output(file_name: str) -> tuple[bool, Any]:
64
64
  """
65
65
  Check if output is available in the HDF5 file
66
66
 
@@ -102,7 +102,7 @@ def get_queue_id(file_name: Optional[str]) -> Optional[int]:
102
102
  return None
103
103
 
104
104
 
105
- def get_cache_data(cache_directory: str) -> List[dict]:
105
+ def get_cache_data(cache_directory: str) -> list[dict]:
106
106
  file_lst = []
107
107
  for file_name in os.listdir(cache_directory):
108
108
  with h5py.File(os.path.join(cache_directory, file_name), "r") as hdf:
@@ -2,7 +2,7 @@ import inspect
2
2
  import multiprocessing
3
3
  import os.path
4
4
  from concurrent.futures import Executor
5
- from typing import Callable, List, Optional
5
+ from typing import Callable, Optional
6
6
 
7
7
 
8
8
  def check_oversubscribe(oversubscribe: bool) -> None:
@@ -16,7 +16,7 @@ def check_oversubscribe(oversubscribe: bool) -> None:
16
16
  )
17
17
 
18
18
 
19
- def check_command_line_argument_lst(command_line_argument_lst: List[str]) -> None:
19
+ def check_command_line_argument_lst(command_line_argument_lst: list[str]) -> None:
20
20
  """
21
21
  Check if command_line_argument_lst is not empty and raise a ValueError if it is.
22
22
  """
@@ -63,7 +63,7 @@ def check_resource_dict(function: Callable) -> None:
63
63
  """
64
64
  Check if the function has a parameter named 'resource_dict' and raise a ValueError if it does.
65
65
  """
66
- if "resource_dict" in inspect.signature(function).parameters.keys():
66
+ if "resource_dict" in inspect.signature(function).parameters:
67
67
  raise ValueError(
68
68
  "The parameter resource_dict is used internally in executorlib, "
69
69
  "so it cannot be used as a parameter in the submitted functions."
@@ -185,13 +185,12 @@ def validate_number_of_cores(
185
185
  return int(max_cores / cores_per_worker)
186
186
  elif max_workers is not None:
187
187
  return int(max_workers)
188
+ elif max_cores is None and max_workers is None and not set_local_cores:
189
+ raise ValueError(
190
+ "Block allocation requires a fixed set of computational resources. Neither max_cores nor max_workers are defined."
191
+ )
188
192
  else:
189
- if max_cores is None and max_workers is None and not set_local_cores:
190
- raise ValueError(
191
- "Block allocation requires a fixed set of computational resources. Neither max_cores nor max_workers are defined."
192
- )
193
- else:
194
- return multiprocessing.cpu_count()
193
+ return multiprocessing.cpu_count()
195
194
 
196
195
 
197
196
  def check_file_exists(file_name: Optional[str]):
@@ -94,5 +94,5 @@ def _update_dict_delta(
94
94
  return {
95
95
  k: v
96
96
  for k, v in dict_input.items()
97
- if k in keys_possible_lst and k not in dict_output.keys()
97
+ if k in keys_possible_lst and k not in dict_output
98
98
  }
@@ -1,6 +1,6 @@
1
1
  import sys
2
2
  from socket import gethostname
3
- from typing import Optional, Tuple
3
+ from typing import Optional
4
4
 
5
5
  import cloudpickle
6
6
  import zmq
@@ -44,7 +44,7 @@ class SocketInterface:
44
44
  dict: dictionary with response received from the connected client
45
45
  """
46
46
  output = cloudpickle.loads(self._socket.recv())
47
- if "result" in output.keys():
47
+ if "result" in output:
48
48
  return output["result"]
49
49
  else:
50
50
  error_type = output["error_type"].split("'")[1]
@@ -161,7 +161,7 @@ def interface_bootup(
161
161
  return interface
162
162
 
163
163
 
164
- def interface_connect(host: str, port: str) -> Tuple[zmq.Context, zmq.Socket]:
164
+ def interface_connect(host: str, port: str) -> tuple[zmq.Context, zmq.Socket]:
165
165
  """
166
166
  Connect to an existing SocketInterface instance by providing the hostname and the port as strings.
167
167
 
@@ -1,5 +1,5 @@
1
1
  import subprocess
2
- from abc import ABC
2
+ from abc import ABC, abstractmethod
3
3
  from typing import Optional
4
4
 
5
5
  MPI_COMMAND = "mpiexec"
@@ -24,6 +24,7 @@ class BaseSpawner(ABC):
24
24
  self._cores = cores
25
25
  self._openmpi_oversubscribe = openmpi_oversubscribe
26
26
 
27
+ @abstractmethod
27
28
  def bootup(
28
29
  self,
29
30
  command_lst: list[str],
@@ -36,6 +37,7 @@ class BaseSpawner(ABC):
36
37
  """
37
38
  raise NotImplementedError
38
39
 
40
+ @abstractmethod
39
41
  def shutdown(self, wait: bool = True):
40
42
  """
41
43
  Method to shutdown the interface.
@@ -45,6 +47,7 @@ class BaseSpawner(ABC):
45
47
  """
46
48
  raise NotImplementedError
47
49
 
50
+ @abstractmethod
48
51
  def poll(self):
49
52
  """
50
53
  Method to check if the interface is running.
@@ -1,13 +1,13 @@
1
1
  import os.path
2
2
  from concurrent.futures import Future
3
- from typing import Optional, Tuple
3
+ from typing import Optional
4
4
 
5
5
  import cloudpickle
6
6
 
7
7
 
8
8
  def generate_nodes_and_edges(
9
9
  task_hash_dict: dict, future_hash_inverse_dict: dict
10
- ) -> Tuple[list, list]:
10
+ ) -> tuple[list, list]:
11
11
  """
12
12
  Generate nodes and edges for visualization.
13
13
 
@@ -39,7 +39,7 @@ def generate_nodes_and_edges(
39
39
  "label": label,
40
40
  }
41
41
  )
42
- elif isinstance(arg, list) and all([isinstance(a, Future) for a in arg]):
42
+ elif isinstance(arg, list) and all(isinstance(a, Future) for a in arg):
43
43
  for a in arg:
44
44
  add_element(arg=a, link_to=link_to, label=label)
45
45
  else:
@@ -12,7 +12,7 @@ def cancel_items_in_queue(que: queue.Queue):
12
12
  while True:
13
13
  try:
14
14
  item = que.get_nowait()
15
- if isinstance(item, dict) and "future" in item.keys():
15
+ if isinstance(item, dict) and "future" in item:
16
16
  item["future"].cancel()
17
17
  que.task_done()
18
18
  except queue.Empty:
@@ -1,7 +1,7 @@
1
1
  import hashlib
2
2
  import inspect
3
3
  import re
4
- from typing import Callable, Tuple
4
+ from typing import Callable, Optional
5
5
 
6
6
  import cloudpickle
7
7
 
@@ -29,8 +29,11 @@ def cloudpickle_register(ind: int = 2):
29
29
 
30
30
 
31
31
  def serialize_funct_h5(
32
- fn: Callable, fn_args: list = [], fn_kwargs: dict = {}, resource_dict: dict = {}
33
- ) -> Tuple[str, dict]:
32
+ fn: Callable,
33
+ fn_args: Optional[list] = None,
34
+ fn_kwargs: Optional[dict] = None,
35
+ resource_dict: Optional[dict] = None,
36
+ ) -> tuple[str, dict]:
34
37
  """
35
38
  Serialize a function and its arguments and keyword arguments into an HDF5 file.
36
39
 
@@ -53,6 +56,12 @@ def serialize_funct_h5(
53
56
  Tuple[str, dict]: A tuple containing the task key and the serialized data.
54
57
 
55
58
  """
59
+ if fn_args is None:
60
+ fn_args = []
61
+ if fn_kwargs is None:
62
+ fn_kwargs = {}
63
+ if resource_dict is None:
64
+ resource_dict = {}
56
65
  binary_all = cloudpickle.dumps(
57
66
  {"fn": fn, "args": fn_args, "kwargs": fn_kwargs, "resource_dict": resource_dict}
58
67
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: executorlib
3
- Version: 0.0.10
3
+ Version: 0.0.11
4
4
  Summary: Scale serial and MPI-parallel python functions over hundreds of compute nodes all from within a jupyter notebook or serial python process.
5
5
  Author-email: Jan Janssen <janssen@lanl.gov>
6
6
  License: BSD 3-Clause License
@@ -60,7 +60,7 @@ Requires-Dist: networkx<=3.4.2,>=2.8.8; extra == "graph"
60
60
  Provides-Extra: graphnotebook
61
61
  Requires-Dist: pygraphviz<=1.14,>=1.10; extra == "graphnotebook"
62
62
  Requires-Dist: networkx<=3.4.2,>=2.8.8; extra == "graphnotebook"
63
- Requires-Dist: ipython<=8.31.0,>=7.33.0; extra == "graphnotebook"
63
+ Requires-Dist: ipython<=8.32.0,>=7.33.0; extra == "graphnotebook"
64
64
  Provides-Extra: mpi
65
65
  Requires-Dist: mpi4py<=4.0.1,>=3.1.4; extra == "mpi"
66
66
  Provides-Extra: submission
@@ -72,7 +72,7 @@ Requires-Dist: pysqa==0.2.3; extra == "all"
72
72
  Requires-Dist: h5py<=3.12.1,>=3.6.0; extra == "all"
73
73
  Requires-Dist: pygraphviz<=1.14,>=1.10; extra == "all"
74
74
  Requires-Dist: networkx<=3.4.2,>=2.8.8; extra == "all"
75
- Requires-Dist: ipython<=8.31.0,>=7.33.0; extra == "all"
75
+ Requires-Dist: ipython<=8.32.0,>=7.33.0; extra == "all"
76
76
 
77
77
  # executorlib
78
78
  [![Unittests](https://github.com/pyiron/executorlib/actions/workflows/unittest-openmpi.yml/badge.svg)](https://github.com/pyiron/executorlib/actions/workflows/unittest-openmpi.yml)
@@ -7,7 +7,7 @@ pysqa==0.2.3
7
7
  h5py<=3.12.1,>=3.6.0
8
8
  pygraphviz<=1.14,>=1.10
9
9
  networkx<=3.4.2,>=2.8.8
10
- ipython<=8.31.0,>=7.33.0
10
+ ipython<=8.32.0,>=7.33.0
11
11
 
12
12
  [cache]
13
13
  h5py<=3.12.1,>=3.6.0
@@ -19,7 +19,7 @@ networkx<=3.4.2,>=2.8.8
19
19
  [graphnotebook]
20
20
  pygraphviz<=1.14,>=1.10
21
21
  networkx<=3.4.2,>=2.8.8
22
- ipython<=8.31.0,>=7.33.0
22
+ ipython<=8.32.0,>=7.33.0
23
23
 
24
24
  [mpi]
25
25
  mpi4py<=4.0.1,>=3.1.4
@@ -44,7 +44,7 @@ graph = [
44
44
  graphnotebook = [
45
45
  "pygraphviz>=1.10,<=1.14",
46
46
  "networkx>=2.8.8,<=3.4.2",
47
- "ipython>=7.33.0,<=8.31.0",
47
+ "ipython>=7.33.0,<=8.32.0",
48
48
  ]
49
49
  mpi = ["mpi4py>=3.1.4,<=4.0.1"]
50
50
  submission = [
@@ -57,7 +57,42 @@ all = [
57
57
  "h5py>=3.6.0,<=3.12.1",
58
58
  "pygraphviz>=1.10,<=1.14",
59
59
  "networkx>=2.8.8,<=3.4.2",
60
- "ipython>=7.33.0,<=8.31.0",
60
+ "ipython>=7.33.0,<=8.32.0",
61
+ ]
62
+
63
+ [tool.ruff]
64
+ exclude = [".ci_support", "docs", "notebooks", "tests", "setup.py", "_version.py"]
65
+
66
+ [tool.ruff.lint]
67
+ select = [
68
+ # pycodestyle
69
+ "E",
70
+ # Pyflakes
71
+ "F",
72
+ # pyupgrade
73
+ "UP",
74
+ # flake8-bugbear
75
+ "B",
76
+ # flake8-simplify
77
+ "SIM",
78
+ # isort
79
+ "I",
80
+ # flake8-comprehensions
81
+ "C4",
82
+ # eradicate
83
+ "ERA",
84
+ # pylint
85
+ "PL",
86
+ ]
87
+ ignore = [
88
+ # ignore line-length violations
89
+ "E501",
90
+ # Too many arguments in function definition
91
+ "PLR0913",
92
+ # Magic value used in comparison
93
+ "PLR2004",
94
+ # Too many branches
95
+ "PLR0912",
61
96
  ]
62
97
 
63
98
  [tool.setuptools.packages.find]
File without changes
File without changes
File without changes
File without changes
File without changes