diff --git a/changelog.txt b/changelog.txt index 98bae35f0..ff06b9669 100644 --- a/changelog.txt +++ b/changelog.txt @@ -12,7 +12,9 @@ Version 2 Added +++++ + - ``H5Store`` related errors are now included in the public API (#775). + - Users can now access the project which a job belongs to from the job object. Changed +++++++ diff --git a/contributors.yaml b/contributors.yaml index d47b4cca0..0c70154d9 100644 --- a/contributors.yaml +++ b/contributors.yaml @@ -123,4 +123,8 @@ contributors: family-names: Takada given-names: Kody affiliation: "University of Michigan" + - + family-names: Kadar + given-names: Alain + affiliation: "University of Michigan" ... diff --git a/doc/api.rst b/doc/api.rst index f4ca03292..a139d0944 100644 --- a/doc/api.rst +++ b/doc/api.rst @@ -90,6 +90,7 @@ The Job class Job.move Job.open Job.path + Job.project Job.remove Job.reset Job.sp diff --git a/signac/contrib/job.py b/signac/contrib/job.py index 441d9fdf4..8083aaa72 100644 --- a/signac/contrib/job.py +++ b/signac/contrib/job.py @@ -606,6 +606,17 @@ def data(self, new_data): """ self.stores[self.KEY_DATA] = new_data + @property + def project(self): + """Get the project that contains this job. + + Returns + ------- + signac.Project + Returns the project containing this job. + """ + return self._project + def init(self, force=False): """Initialize the job's workspace directory. diff --git a/tests/test_job.py b/tests/test_job.py index 2fea1520e..70ff08db4 100644 --- a/tests/test_job.py +++ b/tests/test_job.py @@ -238,6 +238,23 @@ def test_deepcopy(self): copied_job.sp.a = 3 assert copied_job in self.project + def test_project_access_from_job(self): + job = self.project.open_job({"a": 0}).init() + assert isinstance(job.project, signac.Project) + assert job in job.project + assert job.project.path == self._tmp_pr + + def test_custom_project_access_from_job(self): + # Test a custom project subclass to ensure compatibility with signac-flow's FlowProject + class CustomProject(signac.Project): + pass + + custom_project = CustomProject.get_project(self._tmp_pr) + job = custom_project.open_job({"a": 0}).init() + assert isinstance(job.project, CustomProject) + assert job in job.project + assert job.project.path == self._tmp_pr + class TestJobSpInterface(TestJobBase): def test_interface_read_only(self):