From 7175fc9ba3b6972ebd64592c22c850a620cff2c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Sat, 12 Oct 2024 16:37:15 +0200 Subject: [PATCH 01/10] Implement two suggestions for decorators in pyiron_base --- pyiron_base/__init__.py | 1 + pyiron_base/project/decorator.py | 77 +++++++++++++++++++++++++++++++ tests/unit/flex/test_decorator.py | 39 ++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 pyiron_base/project/decorator.py create mode 100644 tests/unit/flex/test_decorator.py diff --git a/pyiron_base/__init__.py b/pyiron_base/__init__.py index a142f5575..5c28c5d50 100644 --- a/pyiron_base/__init__.py +++ b/pyiron_base/__init__.py @@ -29,6 +29,7 @@ from pyiron_base.jobs.master.interactivewrapper import InteractiveWrapper from pyiron_base.jobs.master.list import ListMaster from pyiron_base.jobs.master.parallel import JobGenerator, ParallelMaster +from pyiron_base.project.decorator import pyiron_job, pyiron_job_simple from pyiron_base.project.external import Notebook, dump, load from pyiron_base.project.generic import Creator, Project from pyiron_base.state import state diff --git a/pyiron_base/project/decorator.py b/pyiron_base/project/decorator.py new file mode 100644 index 000000000..113c7b02d --- /dev/null +++ b/pyiron_base/project/decorator.py @@ -0,0 +1,77 @@ +import inspect +from typing import Optional +from pyiron_base.project.generic import Project +from pyiron_base.jobs.job.extension.server.generic import Server + + +def pyiron_job( + project: Project = Project("."), + host: Optional[str] = None, + queue: Optional[str] = None, + cores: int = 1, + threads: int = 1, + gpus: Optional[int] = None, + run_mode: str = "modal", + new_hdf: bool = True, + output_file_lst: list = [], + output_key_lst: list = [], +): + def pyiron_job_function(funct) -> callable: + def function(*args, **kwargs): + delayed_job_object = project.wrap_python_function( + python_function=funct, + *args, + job_name=None, + automatically_rename=True, + execute_job=False, + delayed=True, + output_file_lst=output_file_lst, + output_key_lst=output_key_lst, + **kwargs, + ) + delayed_job_object._server = Server( + host=host, + queue=queue, + cores=cores, + threads=threads, + gpus=gpus, + run_mode=run_mode, + new_hdf=new_hdf, + ) + return delayed_job_object + return function + return pyiron_job_function + + +def pyiron_job_simple(funct) -> callable: + def function( + *args, + project: Project = Project("."), + resource_dict: dict = {}, + output_file_lst: list = [], + output_key_lst: list = [], + **kwargs + ): + resource_default_dict = { + k: v.default for k, v in inspect.signature(Server).parameters.items() + } + resource_dict.update( + { + k:v for k, v in resource_default_dict.items() + if k not in resource_dict.keys() + } + ) + delayed_job_object = project.wrap_python_function( + python_function=funct, + *args, + job_name=None, + automatically_rename=True, + execute_job=False, + delayed=True, + output_file_lst=output_file_lst, + output_key_lst=output_key_lst, + **kwargs, + ) + delayed_job_object._server = Server(**resource_dict) + return delayed_job_object + return function \ No newline at end of file diff --git a/tests/unit/flex/test_decorator.py b/tests/unit/flex/test_decorator.py new file mode 100644 index 000000000..503b21f64 --- /dev/null +++ b/tests/unit/flex/test_decorator.py @@ -0,0 +1,39 @@ +from pyiron_base._tests import TestWithProject +from pyiron_base import pyiron_job, pyiron_job_simple + + +class TestPythonFunctionDecorator(TestWithProject): + def tearDown(self): + self.project.remove_jobs(recursive=True, silently=True) + + def test_delayed(self): + @pyiron_job(project=self.project) + def my_function_a(a, b=8): + return a + b + + @pyiron_job(project=self.project, cores=2) + def my_function_b(a, b=8): + return a + b + + c = my_function_a(a=1, b=2) + d = my_function_b(a=c, b=3) + self.assertEqual(d.pull(), 6) + nodes_dict, edges_lst = d.get_graph() + self.assertEqual(len(nodes_dict), 6) + self.assertEqual(len(edges_lst), 6) + + def test_delayed_simple(self): + @pyiron_job_simple + def my_function_a(a, b=8): + return a + b + + @pyiron_job_simple + def my_function_b(a, b=8): + return a + b + + c = my_function_a(a=1, b=2, project=self.project) + d = my_function_b(a=c, b=3, project=self.project, resource_dict={"cores": 2}) + self.assertEqual(d.pull(), 6) + nodes_dict, edges_lst = d.get_graph() + self.assertEqual(len(nodes_dict), 6) + self.assertEqual(len(edges_lst), 6) From 25c0b6b91e5bf6c87c8fc00bdefc2de40a67d9f9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 12 Oct 2024 14:46:22 +0000 Subject: [PATCH 02/10] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pyiron_base/project/decorator.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/pyiron_base/project/decorator.py b/pyiron_base/project/decorator.py index 113c7b02d..472e7609d 100644 --- a/pyiron_base/project/decorator.py +++ b/pyiron_base/project/decorator.py @@ -1,7 +1,8 @@ import inspect from typing import Optional -from pyiron_base.project.generic import Project + from pyiron_base.jobs.job.extension.server.generic import Server +from pyiron_base.project.generic import Project def pyiron_job( @@ -39,7 +40,9 @@ def function(*args, **kwargs): new_hdf=new_hdf, ) return delayed_job_object + return function + return pyiron_job_function @@ -50,14 +53,15 @@ def function( resource_dict: dict = {}, output_file_lst: list = [], output_key_lst: list = [], - **kwargs + **kwargs, ): resource_default_dict = { k: v.default for k, v in inspect.signature(Server).parameters.items() } resource_dict.update( { - k:v for k, v in resource_default_dict.items() + k: v + for k, v in resource_default_dict.items() if k not in resource_dict.keys() } ) @@ -74,4 +78,5 @@ def function( ) delayed_job_object._server = Server(**resource_dict) return delayed_job_object - return function \ No newline at end of file + + return function From ed8bdc132a532495016fa2c8f1a4758e0b8a9b86 Mon Sep 17 00:00:00 2001 From: samwaseda Date: Mon, 14 Oct 2024 07:37:40 +0000 Subject: [PATCH 03/10] unify pyiron_job and pyiron_job_simple so that it works with or without parentheses --- pyiron_base/__init__.py | 2 +- pyiron_base/project/decorator.py | 79 +++++++++++++++++-------------- tests/unit/flex/test_decorator.py | 10 ++-- 3 files changed, 51 insertions(+), 40 deletions(-) diff --git a/pyiron_base/__init__.py b/pyiron_base/__init__.py index 5c28c5d50..2bab152cc 100644 --- a/pyiron_base/__init__.py +++ b/pyiron_base/__init__.py @@ -29,7 +29,7 @@ from pyiron_base.jobs.master.interactivewrapper import InteractiveWrapper from pyiron_base.jobs.master.list import ListMaster from pyiron_base.jobs.master.parallel import JobGenerator, ParallelMaster -from pyiron_base.project.decorator import pyiron_job, pyiron_job_simple +from pyiron_base.project.decorator import pyiron_job from pyiron_base.project.external import Notebook, dump, load from pyiron_base.project.generic import Creator, Project from pyiron_base.state import state diff --git a/pyiron_base/project/decorator.py b/pyiron_base/project/decorator.py index 472e7609d..0b75ff8a0 100644 --- a/pyiron_base/project/decorator.py +++ b/pyiron_base/project/decorator.py @@ -5,7 +5,10 @@ from pyiron_base.project.generic import Project +# The combined decorator def pyiron_job( + funct: Optional[callable] = None, + *, project: Project = Project("."), host: Optional[str] = None, queue: Optional[str] = None, @@ -17,10 +20,11 @@ def pyiron_job( output_file_lst: list = [], output_key_lst: list = [], ): - def pyiron_job_function(funct) -> callable: + # This is the actual decorator function that applies to the decorated function + def pyiron_job_function(f) -> callable: def function(*args, **kwargs): delayed_job_object = project.wrap_python_function( - python_function=funct, + python_function=f, *args, job_name=None, automatically_rename=True, @@ -40,43 +44,46 @@ def function(*args, **kwargs): new_hdf=new_hdf, ) return delayed_job_object - return function - return pyiron_job_function - + # If funct is None, it means the decorator is called with arguments (like @pyiron_job(...)) + if funct is None: + return pyiron_job_function -def pyiron_job_simple(funct) -> callable: - def function( - *args, - project: Project = Project("."), - resource_dict: dict = {}, - output_file_lst: list = [], - output_key_lst: list = [], - **kwargs, - ): - resource_default_dict = { - k: v.default for k, v in inspect.signature(Server).parameters.items() - } - resource_dict.update( - { - k: v - for k, v in resource_default_dict.items() - if k not in resource_dict.keys() - } - ) - delayed_job_object = project.wrap_python_function( - python_function=funct, + # If funct is not None, it means the decorator is called without parentheses (like @pyiron_job) + else: + # Assume this usage and handle the decorator like `pyiron_job_simple` + def function( *args, - job_name=None, - automatically_rename=True, - execute_job=False, - delayed=True, - output_file_lst=output_file_lst, - output_key_lst=output_key_lst, + project: Project = Project("."), + resource_dict: dict = {}, + output_file_lst: list = [], + output_key_lst: list = [], **kwargs, - ) - delayed_job_object._server = Server(**resource_dict) - return delayed_job_object + ): + resource_default_dict = { + k: v.default for k, v in inspect.signature(Server).parameters.items() + } + resource_dict.update( + { + k: v + for k, v in resource_default_dict.items() + if k not in resource_dict.keys() + } + ) + delayed_job_object = project.wrap_python_function( + python_function=funct, + *args, + job_name=None, + automatically_rename=True, + execute_job=False, + delayed=True, + output_file_lst=output_file_lst, + output_key_lst=output_key_lst, + **kwargs, + ) + delayed_job_object._server = Server(**resource_dict) + return delayed_job_object + + return function - return function diff --git a/tests/unit/flex/test_decorator.py b/tests/unit/flex/test_decorator.py index 503b21f64..afa822c7d 100644 --- a/tests/unit/flex/test_decorator.py +++ b/tests/unit/flex/test_decorator.py @@ -1,5 +1,6 @@ from pyiron_base._tests import TestWithProject -from pyiron_base import pyiron_job, pyiron_job_simple +from pyiron_base import pyiron_job +import unittest class TestPythonFunctionDecorator(TestWithProject): @@ -23,11 +24,11 @@ def my_function_b(a, b=8): self.assertEqual(len(edges_lst), 6) def test_delayed_simple(self): - @pyiron_job_simple + @pyiron_job def my_function_a(a, b=8): return a + b - @pyiron_job_simple + @pyiron_job def my_function_b(a, b=8): return a + b @@ -37,3 +38,6 @@ def my_function_b(a, b=8): nodes_dict, edges_lst = d.get_graph() self.assertEqual(len(nodes_dict), 6) self.assertEqual(len(edges_lst), 6) + +if __name__ == '__main__': + unittest.main() From d9f552018124fc42613de386dac7900d06ce58ce Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2024 07:39:18 +0000 Subject: [PATCH 04/10] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pyiron_base/project/decorator.py | 2 +- tests/unit/flex/test_decorator.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pyiron_base/project/decorator.py b/pyiron_base/project/decorator.py index 0b75ff8a0..7b3d9c2cd 100644 --- a/pyiron_base/project/decorator.py +++ b/pyiron_base/project/decorator.py @@ -44,6 +44,7 @@ def function(*args, **kwargs): new_hdf=new_hdf, ) return delayed_job_object + return function # If funct is None, it means the decorator is called with arguments (like @pyiron_job(...)) @@ -86,4 +87,3 @@ def function( return delayed_job_object return function - diff --git a/tests/unit/flex/test_decorator.py b/tests/unit/flex/test_decorator.py index afa822c7d..99690482e 100644 --- a/tests/unit/flex/test_decorator.py +++ b/tests/unit/flex/test_decorator.py @@ -39,5 +39,6 @@ def my_function_b(a, b=8): self.assertEqual(len(nodes_dict), 6) self.assertEqual(len(edges_lst), 6) -if __name__ == '__main__': + +if __name__ == "__main__": unittest.main() From 9304258a204e0424ed25e235558482dae79d5d5d Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Mon, 14 Oct 2024 18:01:06 +0200 Subject: [PATCH 05/10] Always require project --- pyiron_base/project/decorator.py | 101 +++++++++++++++++------------- tests/unit/flex/test_decorator.py | 12 ++-- 2 files changed, 64 insertions(+), 49 deletions(-) diff --git a/pyiron_base/project/decorator.py b/pyiron_base/project/decorator.py index 7b3d9c2cd..037d3bf79 100644 --- a/pyiron_base/project/decorator.py +++ b/pyiron_base/project/decorator.py @@ -9,7 +9,6 @@ def pyiron_job( funct: Optional[callable] = None, *, - project: Project = Project("."), host: Optional[str] = None, queue: Optional[str] = None, cores: int = 1, @@ -20,30 +19,60 @@ def pyiron_job( output_file_lst: list = [], output_key_lst: list = [], ): + def get_delayed_object( + *args, + pyiron_project: Project, + python_function: callable, + pyiron_resource_dict: dict, + resource_default_dict: dict, + **kwargs + ): + pyiron_resource_dict.update( + { + k: v + for k, v in resource_default_dict.items() + if k not in pyiron_resource_dict.keys() + } + ) + delayed_job_object = pyiron_project.wrap_python_function( + python_function=python_function, + *args, + job_name=None, + automatically_rename=True, + execute_job=False, + delayed=True, + output_file_lst=output_file_lst, + output_key_lst=output_key_lst, + **kwargs, + ) + delayed_job_object._server = Server(**pyiron_resource_dict) + return delayed_job_object + # This is the actual decorator function that applies to the decorated function def pyiron_job_function(f) -> callable: - def function(*args, **kwargs): - delayed_job_object = project.wrap_python_function( - python_function=f, + def function( + *args, + pyiron_project: Project, + pyiron_resource_dict: dict = {}, + **kwargs + ): + resource_default_dict = { + "host": None, + "queue": None, + "cores": 1, + "threads": 1, + "gpus": None, + "run_mode": "modal", + "new_hdf": True, + } + return get_delayed_object( *args, - job_name=None, - automatically_rename=True, - execute_job=False, - delayed=True, - output_file_lst=output_file_lst, - output_key_lst=output_key_lst, - **kwargs, - ) - delayed_job_object._server = Server( - host=host, - queue=queue, - cores=cores, - threads=threads, - gpus=gpus, - run_mode=run_mode, - new_hdf=new_hdf, + python_function=f, + pyiron_project=pyiron_project, + pyiron_resource_dict=pyiron_resource_dict, + resource_default_dict=resource_default_dict, + **kwargs ) - return delayed_job_object return function @@ -56,34 +85,20 @@ def function(*args, **kwargs): # Assume this usage and handle the decorator like `pyiron_job_simple` def function( *args, - project: Project = Project("."), - resource_dict: dict = {}, - output_file_lst: list = [], - output_key_lst: list = [], + pyiron_project: Project, + pyiron_resource_dict: dict = {}, **kwargs, ): resource_default_dict = { k: v.default for k, v in inspect.signature(Server).parameters.items() } - resource_dict.update( - { - k: v - for k, v in resource_default_dict.items() - if k not in resource_dict.keys() - } - ) - delayed_job_object = project.wrap_python_function( - python_function=funct, + return get_delayed_object( *args, - job_name=None, - automatically_rename=True, - execute_job=False, - delayed=True, - output_file_lst=output_file_lst, - output_key_lst=output_key_lst, - **kwargs, + python_function=funct, + pyiron_project=pyiron_project, + pyiron_resource_dict=pyiron_resource_dict, + resource_default_dict=resource_default_dict, + **kwargs ) - delayed_job_object._server = Server(**resource_dict) - return delayed_job_object return function diff --git a/tests/unit/flex/test_decorator.py b/tests/unit/flex/test_decorator.py index 99690482e..12c2acf0a 100644 --- a/tests/unit/flex/test_decorator.py +++ b/tests/unit/flex/test_decorator.py @@ -8,16 +8,16 @@ def tearDown(self): self.project.remove_jobs(recursive=True, silently=True) def test_delayed(self): - @pyiron_job(project=self.project) + @pyiron_job() def my_function_a(a, b=8): return a + b - @pyiron_job(project=self.project, cores=2) + @pyiron_job(cores=2) def my_function_b(a, b=8): return a + b - c = my_function_a(a=1, b=2) - d = my_function_b(a=c, b=3) + c = my_function_a(a=1, b=2, pyiron_project=self.project) + d = my_function_b(a=c, b=3, pyiron_project=self.project) self.assertEqual(d.pull(), 6) nodes_dict, edges_lst = d.get_graph() self.assertEqual(len(nodes_dict), 6) @@ -32,8 +32,8 @@ def my_function_a(a, b=8): def my_function_b(a, b=8): return a + b - c = my_function_a(a=1, b=2, project=self.project) - d = my_function_b(a=c, b=3, project=self.project, resource_dict={"cores": 2}) + c = my_function_a(a=1, b=2, pyiron_project=self.project) + d = my_function_b(a=c, b=3, pyiron_project=self.project, pyiron_resource_dict={"cores": 2}) self.assertEqual(d.pull(), 6) nodes_dict, edges_lst = d.get_graph() self.assertEqual(len(nodes_dict), 6) From c1083b780600e9ce53c3edddf34d9408ac655d64 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2024 16:01:16 +0000 Subject: [PATCH 06/10] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pyiron_base/project/decorator.py | 11 ++++------- tests/unit/flex/test_decorator.py | 4 +++- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/pyiron_base/project/decorator.py b/pyiron_base/project/decorator.py index 037d3bf79..d9a3800de 100644 --- a/pyiron_base/project/decorator.py +++ b/pyiron_base/project/decorator.py @@ -25,7 +25,7 @@ def get_delayed_object( python_function: callable, pyiron_resource_dict: dict, resource_default_dict: dict, - **kwargs + **kwargs, ): pyiron_resource_dict.update( { @@ -51,10 +51,7 @@ def get_delayed_object( # This is the actual decorator function that applies to the decorated function def pyiron_job_function(f) -> callable: def function( - *args, - pyiron_project: Project, - pyiron_resource_dict: dict = {}, - **kwargs + *args, pyiron_project: Project, pyiron_resource_dict: dict = {}, **kwargs ): resource_default_dict = { "host": None, @@ -71,7 +68,7 @@ def function( pyiron_project=pyiron_project, pyiron_resource_dict=pyiron_resource_dict, resource_default_dict=resource_default_dict, - **kwargs + **kwargs, ) return function @@ -98,7 +95,7 @@ def function( pyiron_project=pyiron_project, pyiron_resource_dict=pyiron_resource_dict, resource_default_dict=resource_default_dict, - **kwargs + **kwargs, ) return function diff --git a/tests/unit/flex/test_decorator.py b/tests/unit/flex/test_decorator.py index 12c2acf0a..9ecece73c 100644 --- a/tests/unit/flex/test_decorator.py +++ b/tests/unit/flex/test_decorator.py @@ -33,7 +33,9 @@ def my_function_b(a, b=8): return a + b c = my_function_a(a=1, b=2, pyiron_project=self.project) - d = my_function_b(a=c, b=3, pyiron_project=self.project, pyiron_resource_dict={"cores": 2}) + d = my_function_b( + a=c, b=3, pyiron_project=self.project, pyiron_resource_dict={"cores": 2} + ) self.assertEqual(d.pull(), 6) nodes_dict, edges_lst = d.get_graph() self.assertEqual(len(nodes_dict), 6) From 80c06708f79553de7aff631b669ec91372093b44 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Mon, 14 Oct 2024 18:43:11 +0200 Subject: [PATCH 07/10] add docstring --- pyiron_base/project/decorator.py | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/pyiron_base/project/decorator.py b/pyiron_base/project/decorator.py index 037d3bf79..98477ccc1 100644 --- a/pyiron_base/project/decorator.py +++ b/pyiron_base/project/decorator.py @@ -19,6 +19,41 @@ def pyiron_job( output_file_lst: list = [], output_key_lst: list = [], ): + """ + Decorator to create a pyiron job object from any python function + + Args: + funct (callable): python function to create a job object from + host (str): the hostname of the current system. + queue (str): the queue selected for a current simulation. + cores (int): the number of cores selected for the current simulation. + threads (int): the number of threads selected for the current simulation. + gpus (int): the number of gpus selected for the current simulation. + run_mode (str): the run mode of the job ['modal', 'non_modal', 'queue', 'manual'] + new_hdf (bool): defines whether a subjob should be stored in the same HDF5 file or in a new one. + output_file_lst (list): + output_key_lst (list): + + Returns: + callable: The decorated functions + + Example: + >>> from pyiron_base import pyiron_job, Project + >>> + >>> @pyiron_job + >>> def my_function_a(a, b=8): + >>> return a + b + >>> + >>> @pyiron_job(cores=2) + >>> def my_function_b(a, b=8): + >>> return a + b + >>> + >>> pr = Project("test") + >>> c = my_function_a(a=1, b=2, pyiron_project=pr) + >>> d = my_function_b(a=c, b=3, pyiron_project=pr) + >>> print(d.pull()) + + """ def get_delayed_object( *args, pyiron_project: Project, From 41766bfe37267a436167758908e1f5706fc732bd Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2024 16:43:25 +0000 Subject: [PATCH 08/10] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pyiron_base/project/decorator.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyiron_base/project/decorator.py b/pyiron_base/project/decorator.py index cf93bfd51..55e643f2f 100644 --- a/pyiron_base/project/decorator.py +++ b/pyiron_base/project/decorator.py @@ -54,6 +54,7 @@ def pyiron_job( >>> print(d.pull()) """ + def get_delayed_object( *args, pyiron_project: Project, From 2ac20e926daba180397566faf634a4bfee245a2e Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Tue, 15 Oct 2024 09:22:57 +0200 Subject: [PATCH 09/10] Update pyiron_base/project/decorator.py Co-authored-by: Sam Dareska <37879103+samwaseda@users.noreply.github.com> --- pyiron_base/project/decorator.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyiron_base/project/decorator.py b/pyiron_base/project/decorator.py index 55e643f2f..df0c46dce 100644 --- a/pyiron_base/project/decorator.py +++ b/pyiron_base/project/decorator.py @@ -53,6 +53,7 @@ def pyiron_job( >>> d = my_function_b(a=c, b=3, pyiron_project=pr) >>> print(d.pull()) + Output: 6 """ def get_delayed_object( From 5b2eb0fe19819e9451abfad65aa3f275de52d243 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Tue, 15 Oct 2024 09:23:40 +0200 Subject: [PATCH 10/10] Update pyiron_base/project/decorator.py Co-authored-by: Sam Dareska <37879103+samwaseda@users.noreply.github.com> --- pyiron_base/project/decorator.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/pyiron_base/project/decorator.py b/pyiron_base/project/decorator.py index df0c46dce..36915ed28 100644 --- a/pyiron_base/project/decorator.py +++ b/pyiron_base/project/decorator.py @@ -64,13 +64,9 @@ def get_delayed_object( resource_default_dict: dict, **kwargs, ): - pyiron_resource_dict.update( - { - k: v - for k, v in resource_default_dict.items() - if k not in pyiron_resource_dict.keys() - } - ) + for k, v in resource_default_dict.items(): + if k not in pyiron_resource_dict: + pyiron_resource_dict[k] = v delayed_job_object = pyiron_project.wrap_python_function( python_function=python_function, *args,