From 993ee385760af76f15f39bbb6cea29b213554855 Mon Sep 17 00:00:00 2001 From: Niklas Siemer <70580458+niklassiemer@users.noreply.github.com> Date: Wed, 10 Jan 2024 17:48:16 +0100 Subject: [PATCH 1/7] Remove sql_query functionality to prepare unified db backends --- pyiron_base/database/filetable.py | 2 -- pyiron_base/database/jobtable.py | 30 ++++++++---------------------- pyiron_base/jobs/job/generic.py | 1 - pyiron_base/project/generic.py | 18 ++---------------- pyiron_base/project/jobloader.py | 5 ----- pyiron_base/storage/hdfio.py | 24 ------------------------ 6 files changed, 10 insertions(+), 70 deletions(-) diff --git a/pyiron_base/database/filetable.py b/pyiron_base/database/filetable.py index d6a5b03ce..a79132c89 100644 --- a/pyiron_base/database/filetable.py +++ b/pyiron_base/database/filetable.py @@ -331,7 +331,6 @@ def get_jobs(self, project=None, recursive=True, columns=None): if columns is None: columns = ["id", "project"] df = self.job_table( - sql_query=None, user=None, project_path=project, recursive=recursive, @@ -599,7 +598,6 @@ def _get_job_status_from_hdf5(self, job_id): def _get_job_table( self, - sql_query, user, project_path=None, recursive=True, diff --git a/pyiron_base/database/jobtable.py b/pyiron_base/database/jobtable.py index cf379bd12..c2601dba1 100644 --- a/pyiron_base/database/jobtable.py +++ b/pyiron_base/database/jobtable.py @@ -20,13 +20,12 @@ __date__ = "Sep 1, 2017" -def get_jobs(database, sql_query, user, project_path, recursive=True, columns=None): +def get_jobs(database, user, project_path, recursive=True, columns=None): """ Internal function to return the jobs as dictionary rather than a pandas.Dataframe Args: database (DatabaseAccess): Database object - sql_query (str): SQL query to enter a more specific request user (str): username of the user whoes user space should be searched project_path (str): root_path - this is in contrast to the project_path in GenericPath recursive (bool): search subprojects [True/False] @@ -41,7 +40,6 @@ def get_jobs(database, sql_query, user, project_path, recursive=True, columns=No if columns is None: columns = ["id", "project"] df = database.job_table( - sql_query=sql_query, user=user, project_path=project_path, recursive=recursive, @@ -56,13 +54,12 @@ def get_jobs(database, sql_query, user, project_path, recursive=True, columns=No ) -def get_job_ids(database, sql_query, user, project_path, recursive=True): +def get_job_ids(database, user, project_path, recursive=True): """ Return the job IDs matching a specific query Args: database (DatabaseAccess): Database object - sql_query (str): SQL query to enter a more specific request user (str): username of the user whoes user space should be searched project_path (str): root_path - this is in contrast to the project_path in GenericPath recursive (bool): search subprojects [True/False] @@ -73,7 +70,6 @@ def get_job_ids(database, sql_query, user, project_path, recursive=True): if not isinstance(database, FileTable): return get_jobs( database=database, - sql_query=sql_query, user=user, project_path=project_path, recursive=recursive, @@ -82,13 +78,12 @@ def get_job_ids(database, sql_query, user, project_path, recursive=True): return database.get_job_ids(project=project_path, recursive=recursive) -def get_child_ids(database, sql_query, user, project_path, job_specifier, status=None): +def get_child_ids(database, user, project_path, job_specifier, status=None): """ Get the childs for a specific job Args: database (DatabaseAccess): Database object - sql_query (str): SQL query to enter a more specific request user (str): username of the user whoes user space should be searched project_path (str): root_path - this is in contrast to the project_path in GenericPath job_specifier (str): name of the master job or the master jobs job ID @@ -98,7 +93,7 @@ def get_child_ids(database, sql_query, user, project_path, job_specifier, status list: list of child IDs """ if not isinstance(database, FileTable): - id_master = get_job_id(database, sql_query, user, project_path, job_specifier) + id_master = get_job_id(database, user, project_path, job_specifier) if id_master is None: return [] else: @@ -117,13 +112,12 @@ def get_child_ids(database, sql_query, user, project_path, job_specifier, status return database.get_child_ids(job_specifier=job_specifier, project=project_path) -def get_job_id(database, sql_query, user, project_path, job_specifier): +def get_job_id(database, user, project_path, job_specifier): """ get the job_id for job named job_name in the local project path from database Args: database (DatabaseAccess): Database object - sql_query (str): SQL query to enter a more specific request user (str): username of the user whoes user space should be searched project_path (str): root_path - this is in contrast to the project_path in GenericPath job_specifier (str): name of the job or job ID @@ -136,7 +130,6 @@ def get_job_id(database, sql_query, user, project_path, job_specifier): return job_specifier # is id job_dict = database._job_dict( - sql_query=sql_query, user=user, project_path=project_path, recursive=False, @@ -144,7 +137,6 @@ def get_job_id(database, sql_query, user, project_path, job_specifier): ) if len(job_dict) == 0: job_dict = database._job_dict( - sql_query=sql_query, user=user, project_path=project_path, recursive=True, @@ -164,13 +156,12 @@ def get_job_id(database, sql_query, user, project_path, job_specifier): return database.get_job_id(job_specifier=job_specifier, project=project_path) -def set_job_status(database, sql_query, user, project_path, job_specifier, status): +def set_job_status(database, user, project_path, job_specifier, status): """ Set the status of a particular job Args: database (DatabaseAccess/ FileTable): Database object - sql_query (str): SQL query to enter a more specific request user (str): username of the user whoes user space should be searched project_path (str): root_path - this is in contrast to the project_path in GenericPath job_specifier (str): name of the job or job ID @@ -181,7 +172,6 @@ def set_job_status(database, sql_query, user, project_path, job_specifier, statu database.set_job_status( job_id=get_job_id( database=database, - sql_query=sql_query, user=user, project_path=project_path, job_specifier=job_specifier, @@ -190,13 +180,12 @@ def set_job_status(database, sql_query, user, project_path, job_specifier, statu ) -def get_job_status(database, sql_query, user, project_path, job_specifier): +def get_job_status(database, user, project_path, job_specifier): """ Get the status of a particular job Args: database (DatabaseAccess): Database object - sql_query (str): SQL query to enter a more specific request user (str): username of the user whoes user space should be searched project_path (str): root_path - this is in contrast to the project_path in GenericPath job_specifier (str): name of the job or job ID @@ -209,7 +198,6 @@ def get_job_status(database, sql_query, user, project_path, job_specifier): return database.get_job_status( job_id=get_job_id( database=database, - sql_query=sql_query, user=user, project_path=project_path, job_specifier=job_specifier, @@ -217,13 +205,12 @@ def get_job_status(database, sql_query, user, project_path, job_specifier): ) -def get_job_working_directory(database, sql_query, user, project_path, job_specifier): +def get_job_working_directory(database, user, project_path, job_specifier): """ Get the working directory of a particular job Args: database (DatabaseAccess): Database object - sql_query (str): SQL query to enter a more specific request user (str): username of the user whoes user space should be searched project_path (str): root_path - this is in contrast to the project_path in GenericPath job_specifier (str): name of the job or job ID @@ -234,7 +221,6 @@ def get_job_working_directory(database, sql_query, user, project_path, job_speci return database.get_job_working_directory( job_id=get_job_id( database=database, - sql_query=sql_query, user=user, project_path=project_path, job_specifier=job_specifier, diff --git a/pyiron_base/jobs/job/generic.py b/pyiron_base/jobs/job/generic.py index e26cf1de5..a5222b5d0 100644 --- a/pyiron_base/jobs/job/generic.py +++ b/pyiron_base/jobs/job/generic.py @@ -787,7 +787,6 @@ def transfer_from_remote(self): else: ft = FileTable(index_from=self.project_hdf5.path + "_hdf5/") df = ft.job_table( - sql_query=None, user=state.settings.login_user, project_path=None, all_columns=True, diff --git a/pyiron_base/project/generic.py b/pyiron_base/project/generic.py index da7de5b65..16db032fa 100644 --- a/pyiron_base/project/generic.py +++ b/pyiron_base/project/generic.py @@ -80,7 +80,6 @@ class Project(ProjectPath, HasGroups): path (GenericPath, str): path of the project defined by GenericPath, absolute or relative (with respect to current working directory) path user (str): current pyiron user - sql_query (str): SQL query to only select a subset of the existing jobs within the current project default_working_directory (bool): Access default working directory, for ScriptJobs this equals the project directory of the ScriptJob for regular projects it falls back to the current directory. @@ -94,7 +93,6 @@ class Project(ProjectPath, HasGroups): history (): Previously opened projects / folders. parent_group (): Parent project - one level above the current project. user (): Current unix/linux/windows user who is running pyiron - sql_query (): An SQL query to limit the jobs within the project to a subset which matches the SQL query. db (): Connection to the SQL database. job_type (): Job Type object with all the available job types: ['ExampleJob', 'SerialMaster', 'ParallelMaster', 'ScriptJob', 'ListMaster']. @@ -113,9 +111,7 @@ class Project(ProjectPath, HasGroups): {'foo': 42} """ - def __init__( - self, path="", user=None, sql_query=None, default_working_directory=False - ): + def __init__(self, path="", user=None, default_working_directory=False): if default_working_directory and path == "": inputdict = Notebook.get_custom_dict() if inputdict is not None and "project_dir" in inputdict.keys(): @@ -126,7 +122,6 @@ def __init__( super(Project, self).__init__(path=path) self.user = user - self.sql_query = sql_query self._filter = ["groups", "nodes", "objects"] self._inspect_mode = False self._data = None @@ -223,7 +218,7 @@ def copy(self): Returns: Project: copy of the project object """ - new = self.__class__(path=self.path, user=self.user, sql_query=self.sql_query) + new = self.__class__(path=self.path, user=self.user) new._filter = self._filter new._inspect_mode = self._inspect_mode return new @@ -452,7 +447,6 @@ def get_child_ids(self, job_specifier, project=None): project = self.project_path return get_child_ids( database=self.db, - sql_query=self.sql_query, user=self.user, project_path=project, job_specifier=job_specifier, @@ -499,7 +493,6 @@ def get_jobs(self, recursive=True, columns=None): """ return get_jobs( database=self.db, - sql_query=self.sql_query, user=self.user, project_path=self.project_path, recursive=recursive, @@ -518,7 +511,6 @@ def get_job_ids(self, recursive=True): """ return get_job_ids( database=self.db, - sql_query=self.sql_query, user=self.user, project_path=self.project_path, recursive=recursive, @@ -536,7 +528,6 @@ def get_job_id(self, job_specifier): """ return get_job_id( database=self.db, - sql_query=self.sql_query, user=self.user, project_path=self.project_path, job_specifier=job_specifier, @@ -558,7 +549,6 @@ def get_job_status(self, job_specifier, project=None): project = self.project_path return get_job_status( database=self.db, - sql_query=self.sql_query, user=self.user, project_path=project, job_specifier=job_specifier, @@ -578,7 +568,6 @@ def get_job_working_directory(self, job_specifier, project=None): if project is None: project = self.project_path return get_job_working_directory( - sql_query=self.sql_query, user=self.user, project_path=project, database=self.db, @@ -762,7 +751,6 @@ def job_table( if not isinstance(self.db, FileTable) and auto_refresh_job_status: self.refresh_job_status() job_table = self.db.job_table( - sql_query=self.sql_query, user=self.user, project_path=self.project_path, recursive=recursive, @@ -1063,7 +1051,6 @@ def refresh_job_status(self, *jobs, by_status=["running", "submitted"]): if isinstance(job_specifier, str): job_id = get_job_id( database=self.db, - sql_query=self.sql_query, user=self.user, project_path=self.project_path, job_specifier=job_specifier, @@ -1314,7 +1301,6 @@ def set_job_status(self, job_specifier, status, project=None): project = self.project_path set_job_status( database=self.db, - sql_query=self.sql_query, user=self.user, project_path=project, job_specifier=job_specifier, diff --git a/pyiron_base/project/jobloader.py b/pyiron_base/project/jobloader.py index 5adad370e..f3b2e1216 100644 --- a/pyiron_base/project/jobloader.py +++ b/pyiron_base/project/jobloader.py @@ -54,15 +54,10 @@ def __getitem__(self, item): return self.__getattr__(item) def __call__(self, job_specifier, convert_to_object=None): - if self._project.sql_query is not None: - state.logger.warning( - f"SQL filter '{self._project.sql_query}' is active (may exclude job)" - ) if not isinstance(job_specifier, (int, np.integer)): job_specifier = _get_safe_job_name(name=job_specifier) job_id = get_job_id( database=self._project.db, - sql_query=self._project.sql_query, user=self._project.user, project_path=self._project.project_path, job_specifier=job_specifier, diff --git a/pyiron_base/storage/hdfio.py b/pyiron_base/storage/hdfio.py index c10d40d3d..8e2f42032 100644 --- a/pyiron_base/storage/hdfio.py +++ b/pyiron_base/storage/hdfio.py @@ -899,10 +899,6 @@ class ProjectHDFio(FileHDFio): current unix/linux/windows user who is running pyiron - .. attribute:: sql_query - - an SQL query to limit the jobs within the project to a subset which matches the SQL query. - .. attribute:: db connection to the SQL database @@ -988,26 +984,6 @@ def root_path(self): """ return self._project.root_path - @property - def sql_query(self): - """ - Get the SQL query for the project - - Returns: - str: SQL query - """ - return self._project.sql_query - - @sql_query.setter - def sql_query(self, new_query): - """ - Set the SQL query for the project - - Args: - new_query (str): SQL query - """ - self._project.sql_query = new_query - @property def user(self): """ From cc2a27984e31d10b15fbf5491bf85a1fc9b2f244 Mon Sep 17 00:00:00 2001 From: Niklas Siemer <70580458+niklassiemer@users.noreply.github.com> Date: Tue, 20 Feb 2024 10:56:00 +0100 Subject: [PATCH 2/7] Fix signature --- pyiron_base/database/interface.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyiron_base/database/interface.py b/pyiron_base/database/interface.py index de66fc3f3..250592d79 100644 --- a/pyiron_base/database/interface.py +++ b/pyiron_base/database/interface.py @@ -59,9 +59,9 @@ def viewer_mode(self): @abstractmethod def _get_job_table( self, - sql_query, user, project_path, + sql_query=None, recursive=True, columns=None, element_lst=None, @@ -116,9 +116,9 @@ def _get_filtered_job_table( def job_table( self, - sql_query, user, project_path, + sql_query=None, recursive=True, columns=None, all_columns=False, From f24780c964e8aeb6d5acda5ed4e7d4aeb59d7d6e Mon Sep 17 00:00:00 2001 From: Niklas Siemer <70580458+niklassiemer@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:50:46 +0100 Subject: [PATCH 3/7] Remove sql_query from datamining --- pyiron_base/jobs/datamining.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/pyiron_base/jobs/datamining.py b/pyiron_base/jobs/datamining.py index f035b89f7..04a0f14e3 100644 --- a/pyiron_base/jobs/datamining.py +++ b/pyiron_base/jobs/datamining.py @@ -664,7 +664,6 @@ def to_hdf(self, hdf=None, group_name=None): hdf5_input["project"] = { "path": self._analysis_project.path, "user": self._analysis_project.user, - "sql_query": self._analysis_project.sql_query, "filter": self._analysis_project._filter, "inspect_mode": self._analysis_project._inspect_mode, } @@ -694,7 +693,6 @@ def from_hdf(self, hdf=None, group_name=None): project = self.project.__class__( path=project_dict["path"], user=project_dict["user"], - sql_query=project_dict["sql_query"], ) project._filter = project_dict["filter"] project._inspect_mode = project_dict["inspect_mode"] From c2ce39a5ba565d1bdf10c09452d26055f33196a5 Mon Sep 17 00:00:00 2001 From: Niklas Siemer <70580458+niklassiemer@users.noreply.github.com> Date: Tue, 20 Feb 2024 12:09:45 +0100 Subject: [PATCH 4/7] Remove internal sql_query usage --- pyiron_base/database/generic.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/pyiron_base/database/generic.py b/pyiron_base/database/generic.py index 5d8189a9f..f20c0cf93 100644 --- a/pyiron_base/database/generic.py +++ b/pyiron_base/database/generic.py @@ -258,7 +258,6 @@ def viewer_mode(self, value): def _job_dict( self, - sql_query, user, project_path, recursive, @@ -270,7 +269,6 @@ def _job_dict( Internal function to access the database from the project directly. Args: - sql_query (str): SQL query to enter a more specific request user (str): username of the user whoes user space should be searched project_path (str): root_path - this is in contrast to the project_path in GenericPath recursive (bool): search subprojects [True/False] @@ -315,17 +313,6 @@ def _job_dict( if user is not None: dict_clause["username"] = str(user) # FOR GET_ITEMS_SQL: clause.append("username = '" + self.user + "'") - if sql_query is not None: - # FOR GET_ITEMS_SQL: clause.append(self.sql_query) - if "AND" in sql_query: - cl_split = sql_query.split(" AND ") - elif "and" in sql_query: - cl_split = sql_query.split(" and ") - else: - cl_split = [sql_query] - dict_clause.update( - {str(element.split()[0]): element.split()[2] for element in cl_split} - ) if job is not None: dict_clause["job"] = str(job) @@ -347,7 +334,6 @@ def _job_dict( def _get_job_table( self, - sql_query, user, project_path, recursive=True, @@ -355,7 +341,6 @@ def _get_job_table( element_lst=None, ): job_dict = self._job_dict( - sql_query=sql_query, user=user, project_path=project_path, recursive=recursive, From 7d95d998d6112075b1f0bb1beb09ed22ff966165 Mon Sep 17 00:00:00 2001 From: Niklas Siemer <70580458+niklassiemer@users.noreply.github.com> Date: Tue, 20 Feb 2024 12:13:09 +0100 Subject: [PATCH 5/7] remove more queries --- pyiron_base/database/interface.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/pyiron_base/database/interface.py b/pyiron_base/database/interface.py index 250592d79..39c05e008 100644 --- a/pyiron_base/database/interface.py +++ b/pyiron_base/database/interface.py @@ -118,7 +118,6 @@ def job_table( self, user, project_path, - sql_query=None, recursive=True, columns=None, all_columns=False, @@ -134,7 +133,6 @@ def job_table( Access the job_table. Args: - sql_query (str): SQL query to enter a more specific request user (str): username of the user whoes user space should be searched project_path (str): root_path - this is in contrast to the project_path in GenericPath recursive (bool): search subprojects [True/False] @@ -187,7 +185,6 @@ def job_table( pandas.set_option("display.max_colwidth", max_colwidth) df = self._get_job_table( user=user, - sql_query=sql_query, project_path=project_path, recursive=recursive, columns=columns, From 7b329d06fec74a90395b2d912ac1086a13655f45 Mon Sep 17 00:00:00 2001 From: Niklas Siemer <70580458+niklassiemer@users.noreply.github.com> Date: Tue, 20 Feb 2024 12:24:07 +0100 Subject: [PATCH 6/7] cleanup get/set-state --- pyiron_base/project/generic.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pyiron_base/project/generic.py b/pyiron_base/project/generic.py index 16db032fa..bb0d9b463 100644 --- a/pyiron_base/project/generic.py +++ b/pyiron_base/project/generic.py @@ -774,7 +774,7 @@ def job_table( if not any( [ item in ll - for item in ["sql_query (str)", "user (str)", "project_path (str)"] + for item in ["user (str)", "project_path (str)"] ] ) ] @@ -1604,7 +1604,6 @@ def __getstate__(self): state_dict.update( { "user": self.user, - "sql_query": self.sql_query, "filter": self._filter, "inspect_mode": self._inspect_mode, } @@ -1614,7 +1613,6 @@ def __getstate__(self): def __setstate__(self, state): super().__setstate__(state) self.user = state["user"] - self.sql_query = state["sql_query"] self._filter = state["filter"] self._inspect_mode = state["inspect_mode"] self._data = None From d460b74069a4ec79890cff076b6c36fee86b6af3 Mon Sep 17 00:00:00 2001 From: Niklas Siemer <70580458+niklassiemer@users.noreply.github.com> Date: Tue, 20 Feb 2024 12:26:04 +0100 Subject: [PATCH 7/7] Format black. --- pyiron_base/project/generic.py | 7 +- tests/project/test_project.py | 165 +++++++++++++++++++++------------ 2 files changed, 106 insertions(+), 66 deletions(-) diff --git a/pyiron_base/project/generic.py b/pyiron_base/project/generic.py index bb0d9b463..6d47315f5 100644 --- a/pyiron_base/project/generic.py +++ b/pyiron_base/project/generic.py @@ -771,12 +771,7 @@ def job_table( [ ll for ll in FileTable.job_table.__doc__.split("\n") - if not any( - [ - item in ll - for item in ["user (str)", "project_path (str)"] - ] - ) + if not any([item in ll for item in ["user (str)", "project_path (str)"]]) ] ) diff --git a/tests/project/test_project.py b/tests/project/test_project.py index 6f681d6f6..403d27944 100644 --- a/tests/project/test_project.py +++ b/tests/project/test_project.py @@ -11,7 +11,10 @@ from pyiron_base.project.generic import Project from pyiron_base.project.size import _size_conversion from pyiron_base._tests import ( - PyironTestCase, TestWithProject, TestWithFilledProject, ToyJob + PyironTestCase, + TestWithProject, + TestWithFilledProject, + ToyJob, ) from pyiron_base.jobs.job.toolkit import BaseTools @@ -56,22 +59,30 @@ def test_iterjobs(self): except: self.fail("Iterating over empty project should not raise exception.") - try: for j in self.project.iter_jobs(status="finished"): pass except: - self.fail("Iterating over empty project with set status flag should not raise exception.") + self.fail( + "Iterating over empty project with set status flag should not raise exception." + ) def test_create_job_name(self): - self.assertEqual(self.project.create.job_name(['job', 0.1]), 'job_0d1') - self.assertEqual(self.project.create.job_name(['job', 0.1], special_symbols={'.': 'c'}), 'job_0c1') - self.assertEqual(self.project.create.job_name(['job', 1.0000000000005]), 'job_1d0') - self.assertEqual(self.project.create.job_name(['job', 1.0000000000005], ndigits=None), 'job_1d0000000000005') + self.assertEqual(self.project.create.job_name(["job", 0.1]), "job_0d1") + self.assertEqual( + self.project.create.job_name(["job", 0.1], special_symbols={".": "c"}), + "job_0c1", + ) + self.assertEqual( + self.project.create.job_name(["job", 1.0000000000005]), "job_1d0" + ) + self.assertEqual( + self.project.create.job_name(["job", 1.0000000000005], ndigits=None), + "job_1d0000000000005", + ) class TestProjectOperations(TestWithFilledProject): - def test_size(self): self.assertTrue(self.project.size > 0) @@ -81,11 +92,11 @@ def test__size_conversion(self): 0: (0, "byte"), 50: (50, "byte"), 2000: (1.953125, "kibibyte"), - 2**20: (1.0, "mebibyte"), - 2**30: (1.0, "gibibyte"), - 2**40: (1.0, "tebibyte"), - 2**50: (1.0, "pebibyte"), - 2**60: (1024.0, "pebibyte"), + 2 ** 20: (1.0, "mebibyte"), + 2 ** 30: (1.0, "gibibyte"), + 2 ** 40: (1.0, "tebibyte"), + 2 ** 50: (1.0, "pebibyte"), + 2 ** 60: (1024.0, "pebibyte"), } byte = pint.UnitRegistry().byte @@ -98,7 +109,9 @@ def test__size_conversion(self): def test_job_table(self): df = self.project.job_table() self.assertEqual(len(df), self.n_jobs_filled_with) - self.assertEqual(" ".join(df.status.sort_values().unique()), "aborted finished suspended") + self.assertEqual( + " ".join(df.status.sort_values().unique()), "aborted finished suspended" + ) def test_filtered_job_table(self): # Here we test against the filled project @@ -126,91 +139,106 @@ def test_filtered_job_table(self): self.assertEqual( len(self.project.job_table(recursive=True)), n_jobs, - msg="Expected to find all the jobs the project was filled with" + msg="Expected to find all the jobs the project was filled with", ) self.assertEqual( len(self.project.job_table(recursive=True, status="finished")), - n_finished_jobs + n_finished_jobs, ) self.assertEqual( len(self.project.job_table(recursive=False, status="finished")), - n_top_finished_jobs + n_top_finished_jobs, ) self.assertEqual( len(self.project.job_table(recursive=True, status="suspended")), - n_suspended_jobs + n_suspended_jobs, ) self.assertEqual( len(self.project.job_table(recursive=True, status="aborted")), - n_aborted_jobs + n_aborted_jobs, ) self.assertEqual( len(self.project.job_table(recursive=False, status="suspended")), - n_top_suspended_jobs + n_top_suspended_jobs, ) self.assertEqual( - len(self.project.job_table(recursive=False, hamilton="ToyJob")), - n_top_jobs + len(self.project.job_table(recursive=False, hamilton="ToyJob")), n_top_jobs ) self.assertEqual( - len(self.project.job_table(recursive=True, parentid=None)), - n_jobs + len(self.project.job_table(recursive=True, parentid=None)), n_jobs ) self.assertEqual( len(self.project.job_table(recursive=True, status="finished", job="toy_1")), - n_jobs_named_toy_1 - ) - self.assertEqual( - len(self.project.job_table(recursive=True, job="toy*")), - n_jobs + n_jobs_named_toy_1, ) self.assertEqual( - len(self.project.job_table(recursive=True, job="*_1*")), - n_jobs_named_toy_1 + len(self.project.job_table(recursive=True, job="toy*")), n_jobs ) self.assertEqual( - len(self.project.job_table(recursive=True, job="*_*")), - n_jobs + len(self.project.job_table(recursive=True, job="*_1*")), n_jobs_named_toy_1 ) + self.assertEqual(len(self.project.job_table(recursive=True, job="*_*")), n_jobs) self.assertEqual( len( self.project.job_table(recursive=False, status="finished", job="toy_1") ), - n_top_jobs_named_toy_1 + n_top_jobs_named_toy_1, ) self.assertEqual( - len(self.project.job_table(recursive=True, status="^(?!finished)", mode="regex")), + len( + self.project.job_table( + recursive=True, status="^(?!finished)", mode="regex" + ) + ), n_suspended_jobs + n_aborted_jobs, ) self.assertEqual( - len(self.project.job_table(recursive=True, status="^(?!aborted)", mode="regex")), - n_jobs - n_aborted_jobs + len( + self.project.job_table( + recursive=True, status="^(?!aborted)", mode="regex" + ) + ), + n_jobs - n_aborted_jobs, ) self.assertEqual( len(self.project.job_table(recursive=True, job="^(?!toy_1)", mode="regex")), - n_jobs - n_jobs_named_toy_1 + n_jobs - n_jobs_named_toy_1, ) self.assertEqual( len(self.project.job_table(recursive=True, job="^(?!toy_)", mode="regex")), - 0 + 0, ) self.assertRaises(ValueError, self.project.job_table, gibberish=True) def test_get_iter_jobs(self): self.assertEqual( [ - job.output.data_out for job in self.project.iter_jobs( + job.output.data_out + for job in self.project.iter_jobs( recursive=True, convert_to_object=True ) ], - [101] * self.n_jobs_filled_with + [101] * self.n_jobs_filled_with, + ) + self.assertEqual( + [ + val + for val in self.project.iter_jobs(recursive=False, status="suspended") + ], + [], + ) + self.assertIsInstance( + [ + val + for val in self.project.iter_jobs( + recursive=True, status="suspended", convert_to_object=True + ) + ][0], + ToyJob, ) - self.assertEqual([val for val in self.project.iter_jobs(recursive=False, status="suspended")], []) - self.assertIsInstance([val for val in self.project.iter_jobs(recursive=True, status="suspended", - convert_to_object=True)][0], ToyJob) def test_iter_jobs_without_database(self): - pr = Project('test_iter_jobs_without_database') + pr = Project("test_iter_jobs_without_database") database_disabled = pr.state.settings.configuration["disable_database"] pr.state.update({"disable_database": True}) @@ -229,7 +257,7 @@ def test_iter_jobs_without_database(self): self.assertListEqual( ["toy1", "toy2"], job_names, - msg="Expected to iterate among nested projects even without database" + msg="Expected to iterate among nested projects even without database", ) finally: pr.remove_jobs(recursive=True, silently=True) @@ -238,7 +266,7 @@ def test_iter_jobs_without_database(self): def test_maintenance_get_repository_status(self): df = self.project.maintenance.get_repository_status() - self.assertIn('pyiron_base', df.Module.values) + self.assertIn("pyiron_base", df.Module.values) def test_pickle(self): """Project should be pickle-able.""" @@ -247,7 +275,9 @@ def test_pickle(self): self.assertEqual(project_reload.project_path, self.project.project_path) -@unittest.skipUnless(os.name=="posix", "symlinking is only available on posix platforms") +@unittest.skipUnless( + os.name == "posix", "symlinking is only available on posix platforms" +) class TestProjectSymlink(TestWithFilledProject): """ Test that Project.symlink creates a symlink and unlink removes it again. @@ -275,24 +305,39 @@ def test_symlink(self): except Exception as e: self.fail(f"symlinking twice should have no effect, but raised {e}!") - with self.assertRaises(RuntimeError, msg="symlinking to another folder should raise an error"): + with self.assertRaises( + RuntimeError, msg="symlinking to another folder should raise an error" + ): self.project.symlink("asdf") path = self.project.path.rstrip(os.sep) self.assertTrue(islink(path), "symlink() did not create a symlink!") - self.assertEqual(os.readlink(path), join(self.temp.name, self.project.name), - "symlink() created a wrong symlink!") + self.assertEqual( + os.readlink(path), + join(self.temp.name, self.project.name), + "symlink() created a wrong symlink!", + ) - self.assertCountEqual(nodes, self.project.list_nodes(), "not all nodes present after symlink!") - self.assertCountEqual(groups, self.project.list_groups(), "not all groups present after symlink!") + self.assertCountEqual( + nodes, self.project.list_nodes(), "not all nodes present after symlink!" + ) + self.assertCountEqual( + groups, self.project.list_groups(), "not all groups present after symlink!" + ) self.project.unlink() - self.assertTrue(exists(self.project.path), "unlink() did not restore original directory!") + self.assertTrue( + exists(self.project.path), "unlink() did not restore original directory!" + ) self.assertFalse(islink(path), "unlink() did not remove symlink!") - self.assertCountEqual(nodes, self.project.list_nodes(), "not all nodes present after unlink!") - self.assertCountEqual(groups, self.project.list_groups(), "not all groups present after unlink!") + self.assertCountEqual( + nodes, self.project.list_nodes(), "not all nodes present after unlink!" + ) + self.assertCountEqual( + groups, self.project.list_groups(), "not all groups present after unlink!" + ) try: self.project.unlink() @@ -306,12 +351,12 @@ def setUp(self) -> None: self.tools = BaseTools(self.project) def test_registration(self): - self.project.register_tools('foo', self.tools) + self.project.register_tools("foo", self.tools) with self.assertRaises(AttributeError): - self.project.register_tools('foo', self.tools) # Name taken + self.project.register_tools("foo", self.tools) # Name taken with self.assertRaises(AttributeError): - self.project.register_tools('load', self.tools) # Already another method + self.project.register_tools("load", self.tools) # Already another method -if __name__ == '__main__': +if __name__ == "__main__": unittest.main()