Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch configuration executor List type to Iterable #2943

Merged
merged 6 commits into from
Nov 10, 2023
Merged
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
31 changes: 19 additions & 12 deletions parsl/config.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging
import typeguard

from typing import Callable, List, Optional, Sequence, Union
from typing import Callable, Iterable, Optional, Sequence, Union
from typing_extensions import Literal

from parsl.utils import RepresentationMixin
Expand All @@ -20,9 +20,9 @@ class Config(RepresentationMixin):

Parameters
----------
executors : list of ParslExecutor, optional
List of `ParslExecutor` instances to use for executing tasks.
Default is [:class:`~parsl.executors.threads.ThreadPoolExecutor()`].
executors : sequence of ParslExecutor, optional
List (or other iterable) of `ParslExecutor` instances to use for executing tasks.
Default is (:class:`~parsl.executors.threads.ThreadPoolExecutor()`,).
app_cache : bool, optional
Enable app caching. Default is True.
checkpoint_files : sequence of str, optional
Expand Down Expand Up @@ -73,7 +73,7 @@ class Config(RepresentationMixin):

@typeguard.typechecked
def __init__(self,
executors: Optional[List[ParslExecutor]] = None,
executors: Optional[Iterable[ParslExecutor]] = None,
app_cache: bool = True,
checkpoint_files: Optional[Sequence[str]] = None,
checkpoint_mode: Union[None,
Expand All @@ -92,9 +92,14 @@ def __init__(self,
monitoring: Optional[MonitoringHub] = None,
usage_tracking: bool = False,
initialize_logging: bool = True) -> None:
if executors is None:
executors = [ThreadPoolExecutor()]
self.executors = executors

executors = tuple(executors or [])
if not executors:
executors = (ThreadPoolExecutor(),)

self._executors: Sequence[ParslExecutor] = executors
self._validate_executors()

self.app_cache = app_cache
self.checkpoint_files = checkpoint_files
self.checkpoint_mode = checkpoint_mode
Expand Down Expand Up @@ -125,11 +130,13 @@ def __init__(self,
def executors(self) -> Sequence[ParslExecutor]:
return self._executors

@executors.setter
def executors(self, executors: Sequence[ParslExecutor]):
labels = [e.label for e in executors]
def _validate_executors(self) -> None:

if len(self.executors) == 0:
raise ConfigurationError('At least one executor must be specified')

labels = [e.label for e in self.executors]
duplicates = [e for n, e in enumerate(labels) if e in labels[:n]]
if len(duplicates) > 0:
raise ConfigurationError('Executors must have unique labels ({})'.format(
', '.join(['label={}'.format(repr(d)) for d in duplicates])))
self._executors = executors
Loading