diff --git a/openfl-tutorials/experimental/Global_DP/Workflow_Interface_Mnist_Implementation_1.py b/openfl-tutorials/experimental/Global_DP/Workflow_Interface_Mnist_Implementation_1.py index eaa4e1bfc7a..eb9dfd1fc00 100644 --- a/openfl-tutorials/experimental/Global_DP/Workflow_Interface_Mnist_Implementation_1.py +++ b/openfl-tutorials/experimental/Global_DP/Workflow_Interface_Mnist_Implementation_1.py @@ -39,7 +39,7 @@ # Fixing the seed for result repeatation: remove below to stop repeatable runs # ---------------------------------- random_seed = 5495300300540669060 -g_device = torch.Generator(device='cuda') +g_device = torch.Generator(device="cuda") # Uncomment the line below to use g_cpu if not using cuda # g_device = torch.Generator() # noqa: E800 # NOTE: remove below to stop repeatable runs @@ -601,7 +601,6 @@ def end(self): if __name__ == "__main__": - argparser = argparse.ArgumentParser(description=__doc__) argparser.add_argument( "--config_path", help="Absolute path to the flow configuration file" @@ -615,9 +614,7 @@ def end(self): args = argparser.parse_args() if torch.cuda.is_available(): - device = torch.device( - "cuda:0" - ) + device = torch.device("cuda:0") else: device = torch.device("cpu") @@ -638,8 +635,9 @@ def end(self): "Guadalajara", ] - def callable_to_initialize_collaborator_private_attributes(index, n_collaborators, - batch_size, train_dataset, test_dataset): + def callable_to_initialize_collaborator_private_attributes( + index, n_collaborators, batch_size, train_dataset, test_dataset + ): train = deepcopy(train_dataset) test = deepcopy(test_dataset) train.data = train_dataset.data[index::n_collaborators] @@ -648,8 +646,12 @@ def callable_to_initialize_collaborator_private_attributes(index, n_collaborator test.targets = test_dataset.targets[index::n_collaborators] return { - "train_loader": torch.utils.data.DataLoader(train, batch_size=batch_size, shuffle=True), - "test_loader": torch.utils.data.DataLoader(test, batch_size=batch_size, shuffle=True), + "train_loader": torch.utils.data.DataLoader( + train, batch_size=batch_size, shuffle=True + ), + "test_loader": torch.utils.data.DataLoader( + test, batch_size=batch_size, shuffle=True + ), } collaborators = [] @@ -659,14 +661,19 @@ def callable_to_initialize_collaborator_private_attributes(index, n_collaborator name=collaborator_name, private_attributes_callable=callable_to_initialize_collaborator_private_attributes, # Set `num_gpus=0.1` to `num_gpus=0.0` in order to run this tutorial on CPU - num_cpus=0.0, num_gpus=0.1, # Assuming GPU(s) is available in the machine - index=idx, n_collaborators=len(collaborator_names), - batch_size=batch_size_train, train_dataset=mnist_train, - test_dataset=mnist_test + num_cpus=0.0, + num_gpus=0.1, # Assuming GPU(s) is available in the machine + index=idx, + n_collaborators=len(collaborator_names), + batch_size=batch_size_train, + train_dataset=mnist_train, + test_dataset=mnist_test, ) ) - local_runtime = LocalRuntime(aggregator=aggregator, collaborators=collaborators, backend="ray") + local_runtime = LocalRuntime( + aggregator=aggregator, collaborators=collaborators, backend="ray" + ) print(f"Local runtime collaborators = {local_runtime.collaborators}") top_model_accuracy = 0 diff --git a/openfl-tutorials/experimental/Global_DP/Workflow_Interface_Mnist_Implementation_2.py b/openfl-tutorials/experimental/Global_DP/Workflow_Interface_Mnist_Implementation_2.py index 0a73ee923fd..8d4effa142e 100644 --- a/openfl-tutorials/experimental/Global_DP/Workflow_Interface_Mnist_Implementation_2.py +++ b/openfl-tutorials/experimental/Global_DP/Workflow_Interface_Mnist_Implementation_2.py @@ -35,7 +35,7 @@ random_seed = 5495300300540669060 -g_device = torch.Generator(device='cuda') +g_device = torch.Generator(device="cuda") # Uncomment the line below to use g_cpu if not using cuda # g_device = torch.Generator() # noqa: E800 # NOTE: remove below to stop repeatable runs @@ -580,7 +580,6 @@ def end(self): if __name__ == "__main__": - argparser = argparse.ArgumentParser(description=__doc__) argparser.add_argument( "--config_path", help="Absolute path to the flow configuration file." @@ -594,9 +593,7 @@ def end(self): args = argparser.parse_args() if torch.cuda.is_available(): - device = torch.device( - "cuda:0" - ) + device = torch.device("cuda:0") else: device = torch.device("cpu") @@ -617,8 +614,9 @@ def end(self): "Guadalajara", ] - def callable_to_initialize_collaborator_private_attributes(index, n_collaborators, - batch_size, train_dataset, test_dataset): + def callable_to_initialize_collaborator_private_attributes( + index, n_collaborators, batch_size, train_dataset, test_dataset + ): train = deepcopy(train_dataset) test = deepcopy(test_dataset) train.data = train_dataset.data[index::n_collaborators] @@ -627,8 +625,12 @@ def callable_to_initialize_collaborator_private_attributes(index, n_collaborator test.targets = test_dataset.targets[index::n_collaborators] return { - "train_loader": torch.utils.data.DataLoader(train, batch_size=batch_size, shuffle=True), - "test_loader": torch.utils.data.DataLoader(test, batch_size=batch_size, shuffle=True), + "train_loader": torch.utils.data.DataLoader( + train, batch_size=batch_size, shuffle=True + ), + "test_loader": torch.utils.data.DataLoader( + test, batch_size=batch_size, shuffle=True + ), } collaborators = [] @@ -638,14 +640,19 @@ def callable_to_initialize_collaborator_private_attributes(index, n_collaborator name=collaborator_name, private_attributes_callable=callable_to_initialize_collaborator_private_attributes, # Set `num_gpus=0.1` to `num_gpus=0.0` in order to run this tutorial on CPU - num_cpus=0.0, num_gpus=0.1, # Assuming GPU(s) is available in the machine - index=idx, n_collaborators=len(collaborator_names), - batch_size=batch_size_train, train_dataset=mnist_train, - test_dataset=mnist_test + num_cpus=0.0, + num_gpus=0.1, # Assuming GPU(s) is available in the machine + index=idx, + n_collaborators=len(collaborator_names), + batch_size=batch_size_train, + train_dataset=mnist_train, + test_dataset=mnist_test, ) ) - local_runtime = LocalRuntime(aggregator=aggregator, collaborators=collaborators, backend="ray") + local_runtime = LocalRuntime( + aggregator=aggregator, collaborators=collaborators, backend="ray" + ) print(f"Local runtime collaborators = {local_runtime.collaborators}") best_model = None diff --git a/openfl-tutorials/experimental/Privacy_Meter/cifar10_PM.py b/openfl-tutorials/experimental/Privacy_Meter/cifar10_PM.py index cc400182009..f9d9cf3b23a 100644 --- a/openfl-tutorials/experimental/Privacy_Meter/cifar10_PM.py +++ b/openfl-tutorials/experimental/Privacy_Meter/cifar10_PM.py @@ -146,7 +146,6 @@ def inference(network, test_loader, device): def optimizer_to_device(optimizer, device): - """ Sending the "torch.optim.Optimizer" object into the specified device for model training and inference @@ -581,7 +580,6 @@ def end(self): if __name__ == "__main__": - argparser = argparse.ArgumentParser(description=__doc__) argparser.add_argument( "--audit_dataset_ratio", @@ -663,9 +661,7 @@ def end(self): collaborator_names = ["Portland", "Seattle"] if torch.cuda.is_available(): - device = torch.device( - "cuda:0" - ) + device = torch.device("cuda:0") else: device = torch.device("cpu") @@ -693,9 +689,9 @@ def end(self): train_dataset.targets = Y[:train_dataset_size] test_dataset = deepcopy(cifar_test) - test_dataset.data = X[train_dataset_size:train_dataset_size + test_dataset_size] + test_dataset.data = X[train_dataset_size: train_dataset_size + test_dataset_size] test_dataset.targets = Y[ - train_dataset_size:train_dataset_size + test_dataset_size + train_dataset_size: train_dataset_size + test_dataset_size ] population_dataset = deepcopy(cifar_test) @@ -715,7 +711,8 @@ def end(self): # this function will be called before executing collaborator steps # which will return private attributes dictionary for each collaborator def callable_to_initialize_collaborator_private_attributes( - index, n_collaborators, train_ds, test_ds, population_ds, args): + index, n_collaborators, train_ds, test_ds, population_ds, args + ): # construct the training and test and population dataset local_train = deepcopy(train_ds) local_test = deepcopy(test_ds) @@ -773,7 +770,6 @@ def callable_to_initialize_collaborator_private_attributes( ), } - collaborators = [] for idx, collab_name in enumerate(collaborator_names): collaborators.append( @@ -781,16 +777,23 @@ def callable_to_initialize_collaborator_private_attributes( name=collab_name, private_attributes_callable=callable_to_initialize_collaborator_private_attributes, # If 1 GPU is available in the machine - # Set `num_gpus=0.0` to `num_gpus=0.5` to run on GPU with ray backend with 2 collaborators - num_cpus=0.0, num_gpus=0.0, - index=idx, n_collaborators=len(collaborator_names), - train_ds=train_dataset, test_ds=test_dataset, - population_ds=population_dataset, args=args + # Set `num_gpus=0.0` to `num_gpus=0.5` to run on GPU + # with ray backend with 2 collaborators + num_cpus=0.0, + num_gpus=0.0, + index=idx, + n_collaborators=len(collaborator_names), + train_ds=train_dataset, + test_ds=test_dataset, + population_ds=population_dataset, + args=args, ) ) # Set backend='ray' to use ray-backend - local_runtime = LocalRuntime(aggregator=aggregator, collaborators=collaborators, backend="single_process") + local_runtime = LocalRuntime( + aggregator=aggregator, collaborators=collaborators, backend="single_process" + ) print(f"Local runtime collaborators = {local_runtime.collaborators}") diff --git a/openfl/experimental/interface/fl_spec.py b/openfl/experimental/interface/fl_spec.py index a342a2111f4..c87ce68cae3 100644 --- a/openfl/experimental/interface/fl_spec.py +++ b/openfl/experimental/interface/fl_spec.py @@ -84,7 +84,8 @@ def run(self) -> None: "\nLocalRuntime(...,backend='single_process')\n" "\n or for more information about the original error," "\nPlease see the official Ray documentation" - "\nhttps://docs.ray.io/en/releases-2.2.0/ray-core/objects/serialization.html" + "\nhttps://docs.ray.io/en/releases-2.2.0/ray-core/\ + objects/serialization.html" ) raise SerializationError(str(e) + msg) else: diff --git a/openfl/experimental/interface/participants.py b/openfl/experimental/interface/participants.py index bcedfb96364..5c17c7f76d8 100644 --- a/openfl/experimental/interface/participants.py +++ b/openfl/experimental/interface/participants.py @@ -45,20 +45,20 @@ class Collaborator(Participant): def __init__(self, name: str = "", private_attributes_callable: Callable = None, num_cpus: int = 0, num_gpus: int = 0.0, **kwargs): """ - Create collaborator object with custom resources and a callable + Create collaborator object with custom resources and a callable function to assign private attributes Parameters: name (str): Name of the collaborator. default="" private_attributes_callable (Callable): A function which returns collaborator - private attributes for each collaborator. In case private_attributes are not + private attributes for each collaborator. In case private_attributes are not required this can be omitted. default=None num_cpus (int): Specifies how many cores to use for the collaborator step exection. This will only be used if backend is set to ray. default=0 - num_gpus (float): Specifies how many GPUs to use to accerlerate the collaborator + num_gpus (float): Specifies how many GPUs to use to accerlerate the collaborator step exection. This will only be used if backend is set to ray. default=0 kwargs (dict): Parameters required to call private_attributes_callable function. @@ -84,7 +84,7 @@ def get_name(self) -> str: def initialize_private_attributes(self) -> None: """ - initialize private attributes of Collaborator object by invoking + initialize private attributes of Collaborator object by invoking the callable specified by user """ if self.private_attributes_callable is not None: @@ -92,7 +92,7 @@ def initialize_private_attributes(self) -> None: def __set_collaborator_attrs_to_clone(self, clone: Any) -> None: """ - Set collaborator private attributes to FLSpec clone before transitioning + Set collaborator private attributes to FLSpec clone before transitioning from Aggregator step to collaborator steps """ # set collaborator private attributes as @@ -102,10 +102,10 @@ def __set_collaborator_attrs_to_clone(self, clone: Any) -> None: def __delete_collab_attrs_from_clone(self, clone: Any) -> None: """ - Remove collaborator private attributes from FLSpec clone before + Remove collaborator private attributes from FLSpec clone before transitioning from Collaborator step to Aggregator step """ - # Update collaborator private attributes by taking latest + # Update collaborator private attributes by taking latest # parameters from clone, then delete attributes from clone. for attr_name in self.private_attributes: if hasattr(clone, attr_name): @@ -146,9 +146,8 @@ def __init__(self, name: str = "", private_attributes_callable: Callable = None, def initialize_private_attributes(self) -> None: """ - initialize private attributes of Aggregator object by invoking + initialize private attributes of Aggregator object by invoking the callable specified by user """ if self.private_attributes_callable is not None: self.private_attributes = self.private_attributes_callable(**self.kwargs) - diff --git a/openfl/experimental/runtime/local_runtime.py b/openfl/experimental/runtime/local_runtime.py index a8790942cca..d64510b9b88 100644 --- a/openfl/experimental/runtime/local_runtime.py +++ b/openfl/experimental/runtime/local_runtime.py @@ -9,9 +9,9 @@ import ray import os import gc -import numpy as np from openfl.experimental.runtime import Runtime from typing import TYPE_CHECKING + if TYPE_CHECKING: from openfl.experimental.interface import Aggregator, Collaborator, FLSpec @@ -33,10 +33,11 @@ def __init__(self): """Create RayExecutor object""" self.__remote_contexts = [] - def ray_call_put(self, collaborator: Collaborator, ctx: Any, - f_name: str, callback: Callable) -> None: + def ray_call_put( + self, collaborator: Collaborator, ctx: Any, f_name: str, callback: Callable + ) -> None: """ - Execute f_name from inside collaborator class with the context + Execute f_name from inside collaborator class with the context of clone (ctx) """ self.__remote_contexts.append( @@ -116,19 +117,27 @@ def __get_collaborator_object(self, collaborators: List) -> Any: total_available_cpus = os.cpu_count() total_available_gpus = get_number_of_gpus() - total_required_gpus = sum([collaborator.num_gpus for collaborator in collaborators]) - total_required_cpus = sum([collaborator.num_cpus for collaborator in collaborators]) + total_required_gpus = sum( + [collaborator.num_gpus for collaborator in collaborators] + ) + total_required_cpus = sum( + [collaborator.num_cpus for collaborator in collaborators] + ) if total_required_gpus > 0: - check_resource_allocation(total_available_gpus, {collab.get_name(): collab.num_gpus - for collab in collaborators}) + check_resource_allocation( + total_available_gpus, + {collab.get_name(): collab.num_gpus for collab in collaborators}, + ) if total_available_gpus < total_required_gpus: raise ResourcesNotAvailableError( - f"cannot assign more than available GPUs ({total_required_gpus} < {total_available_gpus})." - ) + f"cannot assign more than available GPUs \ + ({total_required_gpus} < {total_available_gpus})." + ) if total_available_cpus < total_required_cpus: raise ResourcesNotAvailableError( - f"cannot assign more than available CPUs ({total_required_cpus} < {total_available_cpus})." + f"cannot assign more than available CPUs \ + ({total_required_cpus} < {total_available_cpus})." ) interface_module = importlib.import_module("openfl.experimental.interface") collaborator_class = getattr(interface_module, "Collaborator") @@ -139,13 +148,16 @@ def __get_collaborator_object(self, collaborators: List) -> Any: num_gpus = collaborator.num_gpus collaborator_actor = ray.remote(collaborator_class).options( - num_cpus=num_cpus, num_gpus=num_gpus) + num_cpus=num_cpus, num_gpus=num_gpus + ) - collaborator_ray_refs.append(collaborator_actor.remote( - name=collaborator.get_name(), - private_attributes_callable=collaborator.private_attributes_callable, - **collaborator.kwargs - )) + collaborator_ray_refs.append( + collaborator_actor.remote( + name=collaborator.get_name(), + private_attributes_callable=collaborator.private_attributes_callable, + **collaborator.kwargs, + ) + ) return collaborator_ray_refs @property @@ -169,9 +181,14 @@ def collaborators(self) -> List[str]: def collaborators(self, collaborators: List[Type[Collaborator]]): """Set LocalRuntime collaborators""" if self.backend == "single_process": - get_collab_name = lambda collab: collab.get_name() + + def get_collab_name(collab): + return collab.get_name() + else: - get_collab_name = lambda collab: ray.get(collab.get_name.remote()) + + def get_collab_name(collab): + return ray.get(collab.get_name.remote()) self.__collaborators = { get_collab_name(collaborator): collaborator @@ -185,17 +202,20 @@ def initialize_aggregator(self): def initialize_collaborators(self): """initialize collaborator private attributes""" if self.backend == "single_process": - init_private_attrs = lambda collab: collab.initialize_private_attributes() + + def init_private_attrs(collab): + return collab.initialize_private_attributes() + else: - init_private_attrs = lambda collab: collab.initialize_private_attributes.remote() + + def init_private_attrs(collab): + return collab.initialize_private_attributes.remote() for collaborator in self.__collaborators.values(): init_private_attrs(collaborator) def restore_instance_snapshot( - self, - ctx: Type[FLSpec], - instance_snapshot: List[Type[FLSpec]] + self, ctx: Type[FLSpec], instance_snapshot: List[Type[FLSpec]] ): """Restores attributes from backup (in instance snapshot) to ctx""" for backup in instance_snapshot: @@ -206,7 +226,7 @@ def restore_instance_snapshot( def execute_collaborator_steps(self, ctx: Any, f_name: str): """ - Execute collaborator steps for each + Execute collaborator steps for each collaborator until at transition point """ not_at_transition_point = True @@ -279,8 +299,11 @@ def execute_end_task(self, flspec_obj, f): list: updated arguments to be executed """ - interface_module = importlib.import_module("openfl.experimental.interface") - final_attributes = getattr(interface_module, "final_attributes") + from openfl.experimental.interface import ( + final_attributes, + ) + + global final_attributes to_exec = getattr(flspec_obj, f.__name__) to_exec() @@ -325,9 +348,7 @@ def execute_foreach_task( clone = FLSpec._clones[col] if aggregator_to_collaborator(f, parent_func): for attr in self._aggregator.private_attributes: - self._aggregator.private_attributes[attr] = getattr( - clone, attr - ) + self._aggregator.private_attributes[attr] = getattr(clone, attr) if hasattr(clone, attr): delattr(clone, attr) @@ -350,9 +371,13 @@ def execute_foreach_task( collaborator = self.__collaborators[collab_name] if self.backend == "ray": - ray_executor.ray_call_put(collaborator, clone, f.__name__, self.execute_collaborator_steps) + ray_executor.ray_call_put( + collaborator, clone, f.__name__, self.execute_collaborator_steps + ) else: - collaborator.execute_func(clone, f.__name__, self.execute_collaborator_steps) + collaborator.execute_func( + clone, f.__name__, self.execute_collaborator_steps + ) if self.backend == "ray": clones = ray_executor.get_remote_clones() diff --git a/openfl/experimental/utilities/__init__.py b/openfl/experimental/utilities/__init__.py index e0b4d119c80..2272d1459a4 100644 --- a/openfl/experimental/utilities/__init__.py +++ b/openfl/experimental/utilities/__init__.py @@ -10,10 +10,10 @@ collaborator_to_aggregator, ) from .exceptions import ( - SerializationError, - ResourcesNotAvailableError, - ResourcesAllocationError, - ) + SerializationError, + ResourcesNotAvailableError, + ResourcesAllocationError, +) from .stream_redirect import ( RedirectStdStreamBuffer, RedirectStdStream, diff --git a/openfl/experimental/utilities/exceptions.py b/openfl/experimental/utilities/exceptions.py index e89773e09a6..12a307d271e 100644 --- a/openfl/experimental/utilities/exceptions.py +++ b/openfl/experimental/utilities/exceptions.py @@ -12,6 +12,7 @@ def __init__(self, *args: object) -> None: super().__init__(*args) pass + class ResourcesAllocationError(Exception): def __init__(self, *args: object) -> None: super().__init__(*args) diff --git a/openfl/experimental/utilities/metaflow_utils.py b/openfl/experimental/utilities/metaflow_utils.py index 126a86ef0df..ba142ddd811 100644 --- a/openfl/experimental/utilities/metaflow_utils.py +++ b/openfl/experimental/utilities/metaflow_utils.py @@ -201,7 +201,8 @@ def __init__(self, flow): self._postprocess() def _create_nodes(self, flow): - tree = ast.parse(getsource(flow)).body + module = __import__(flow.__module__) + tree = ast.parse(getsource(module)).body root = [ n for n in tree diff --git a/openfl/experimental/utilities/resources.py b/openfl/experimental/utilities/resources.py index 125a2dbd9e4..126c6b0e175 100644 --- a/openfl/experimental/utilities/resources.py +++ b/openfl/experimental/utilities/resources.py @@ -9,4 +9,3 @@ def get_number_of_gpus(): # TODO remove pytorch dependency return device_count() - diff --git a/openfl/experimental/utilities/runtime_utils.py b/openfl/experimental/utilities/runtime_utils.py index 9ac420c4a9c..fa4ae989027 100644 --- a/openfl/experimental/utilities/runtime_utils.py +++ b/openfl/experimental/utilities/runtime_utils.py @@ -96,16 +96,17 @@ def checkpoint(ctx, parent_func, chkpnt_reserved_words=["next", "runtime"]): ) print(f"Saved data artifacts for {parent_func.__name__}") + def check_resource_allocation(num_gpus, each_collab_gpu_usage): remaining_gpu_memory = {} for gpu in np.ones(num_gpus, dtype=int): for i, (collab_name, collab_gpu_usage) in enumerate(each_collab_gpu_usage.items()): if gpu == 0: break - if gpu < collab_gpu_usage: # and collab_gpu_usage > 0: + if gpu < collab_gpu_usage: # and collab_gpu_usage > 0: remaining_gpu_memory.update({collab_name: gpu}) - print (f"each_collab_gpu_usage: {each_collab_gpu_usage}") - print (f"i: {i}") + print(f"each_collab_gpu_usage: {each_collab_gpu_usage}") + print(f"i: {i}") each_collab_gpu_usage = dict(itertools.islice(each_collab_gpu_usage.items(), i)) else: gpu -= collab_gpu_usage diff --git a/tests/github/experimental/testflow_privateattributes.py b/tests/github/experimental/testflow_privateattributes.py index 3b0d653523a..ae320f56f0c 100644 --- a/tests/github/experimental/testflow_privateattributes.py +++ b/tests/github/experimental/testflow_privateattributes.py @@ -105,6 +105,7 @@ def join(self, inputs): ) for input in enumerate(inputs): + collab = input[1].input if ( hasattr(input, "train_loader") is True or hasattr(input, "test_loader") is True @@ -114,7 +115,7 @@ def join(self, inputs): "join_collaborator_attributes_found" ) print( - f"{bcolors.FAIL} ... Attribute test failed in Join - COllaborator: {collab}" + f"{bcolors.FAIL} ... Attribute test failed in Join - Collaborator: {collab}" + f" private attributes accessible {bcolors.ENDC}" ) @@ -239,7 +240,9 @@ def callable_to_initialize_collaborator_private_attributes(index): if len(sys.argv) > 1 and sys.argv[1] == "ray": backend = "ray" - local_runtime = LocalRuntime(aggregator=aggregator, collaborators=collaborators, backend=backend) + local_runtime = LocalRuntime( + aggregator=aggregator, collaborators=collaborators, backend=backend + ) print(f"Local runtime collaborators = {local_runtime.collaborators}") flflow = TestFlowPrivateAttributes(checkpoint=True) diff --git a/tests/github/experimental/testflow_reference.py b/tests/github/experimental/testflow_reference.py index c6ff2493122..16dc38914f8 100644 --- a/tests/github/experimental/testflow_reference.py +++ b/tests/github/experimental/testflow_reference.py @@ -242,7 +242,7 @@ def find_matched_references(collab_attr_list, all_collaborators): for attr_name in collab_attr_list: for i, curr_collab in enumerate(all_collaborators): # Compare the current collaborator with the collaborator(s) that come(s) after it. - for next_collab in all_collaborators[i + 1 :]: + for next_collab in all_collaborators[i + 1:]: # Check if both collaborators have the current attribute if hasattr(curr_collab, attr_name) and hasattr(next_collab, attr_name): # Check if both collaborators are sharing same reference @@ -336,13 +336,13 @@ def validate_agg_collab_references(all_collborators, agg_obj, agg_attrs): if __name__ == "__main__": # Setup participants aggregator = Aggregator() - + # Setup collaborators private attributes via callable function collaborator_names = ["Portland", "Seattle", "Chandler", "Bangalore"] def callable_to_initialize_collaborator_private_attributes(index): return {"index": index + 1} - + collaborators = [] for idx, collaborator_name in enumerate(collaborator_names): collaborators.append( diff --git a/tests/github/experimental/testflow_reference_with_exclude.py b/tests/github/experimental/testflow_reference_with_exclude.py index 04295c27599..0b5ffa93b75 100644 --- a/tests/github/experimental/testflow_reference_with_exclude.py +++ b/tests/github/experimental/testflow_reference_with_exclude.py @@ -206,7 +206,7 @@ def find_matched_references(collab_attr_list, all_collaborators): for attr_name in collab_attr_list: for i, curr_collab in enumerate(all_collaborators): # Compare the current collaborator with the collaborator(s) that come(s) after it. - for next_collab in all_collaborators[i + 1 :]: + for next_collab in all_collaborators[i + 1:]: # Check if both collaborators have the current attribute if hasattr(curr_collab, attr_name) and hasattr(next_collab, attr_name): # Check if both collaborators are sharing same reference diff --git a/tests/github/experimental/testflow_reference_with_include.py b/tests/github/experimental/testflow_reference_with_include.py index 5003c6752fd..954b20ae5a5 100644 --- a/tests/github/experimental/testflow_reference_with_include.py +++ b/tests/github/experimental/testflow_reference_with_include.py @@ -203,7 +203,7 @@ def find_matched_references(collab_attr_list, all_collaborators): for attr_name in collab_attr_list: for i, curr_collab in enumerate(all_collaborators): # Compare the current collaborator with the collaborator(s) that come(s) after it. - for next_collab in all_collaborators[i + 1 :]: + for next_collab in all_collaborators[i + 1:]: # Check if both collaborators have the current attribute if hasattr(curr_collab, attr_name) and hasattr(next_collab, attr_name): # Check if both collaborators are sharing same reference