vishav1771: @jglaser @csadorf Some tests are failing. Can you help me fix the issues?
bdice: @vishav1771 Those tests are checking the assumptions of the old behavior. Since you changed the behavior, you will also need to update those tests. If you look at the test outputs, it will help you find the code to change. See the very bottom of this page for the error outputs: https://circleci.com/gh/glotzerlab/signac/4716

```python
======================================================================
ERROR: test_workspace_read_only_path (test_project.CachedProjectTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/circleci/repo/tests/test_project.py", line 237, in test_workspace_read_only_path
    with open(os.path.join(self.project.workspace()), 'w'):
IsADirectoryError: [Errno 21] Is a directory: '/tmp/signac_5zyno0sl/wd'

======================================================================
ERROR: test_workspace_read_only_path (test_project.ProjectTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/circleci/repo/tests/test_project.py", line 237, in test_workspace_read_only_path
    with open(os.path.join(self.project.workspace()), 'w'):
IsADirectoryError: [Errno 21] Is a directory: '/tmp/signac_qq_kwy8m/wd'

======================================================================
FAIL: test_no_workspace_warn_on_find (test_project.CachedProjectTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/circleci/repo/tests/test_project.py", line 217, in test_no_workspace_warn_on_find
    self.assertFalse(os.path.exists(self.project.workspace()))
AssertionError: True is not false

======================================================================
FAIL: test_no_workspace_warn_on_find (test_project.ProjectTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/circleci/repo/tests/test_project.py", line 217, in test_no_workspace_warn_on_find
    self.assertFalse(os.path.exists(self.project.workspace()))
AssertionError: True is not false
```

For the first two tests, you'll see a comment right above line 237 in `test_project.py`. It says:
```python
        # Create file where workspace would be, thus preventing the creation
        # of the workspace directory.
```
The purpose of `test_workspace_read_only_path` is to check the behavior if a workspace cannot be created. This test makes a **file** called `workspace`, which prevents the creation of the **directory** `workspace`. To fix this test, you'll need to add a line at the beginning of that test that removes the existing workspace directory before it makes the file.

The purpose of `test_no_workspace_warn_on_find` is to make sure that the user is warned if they attempt to search for jobs and no workspace directory is found. You should do the same thing here, just remove the workspace directory at the beginning of the test.
csadorf: > @vishav1771 Those tests are checking the assumptions of the old behavior. Since you changed the behavior, you will also need to update those tests.

Just because it was not explicitly mentioned, I would like to point out that **changing existing unit tests is generally not appropriate** since this means that the patch introduces a change in behavior that is likely backwards-incompatible.

We should therefore carefully analyze in the review 
- what the exact nature of this change is,
- whether it is avoidable, and
- what possible implications it may have on users who implicitly or explicitly rely on the current behavior, and
- whether we should delay the release of this breaking change until the next major version increase.

@vishav1771 All of your changes are fine, I just want to make sure the reviewers are sensitive to this issue.
vishav1771: @bdice I have done the changes you asked.
bdice: @vishav1771 Thanks! I reviewed the PR checklist at the top and there are a couple of next steps:
- Add yourself to the list of contributors (edit `contributors.yaml`)
- Add a **new** test that checks if the workspace directory exists after the project is initialized, so that we guarantee this behavior in the future (you might call it `test_workspace_directory_exists` in `test_project.py`)
- Update the changelog with a short sentence documenting the change in behavior, and include the issue and PR numbers in parentheses (just follow the pattern). Put it under these headers:
```
Version 1
=========

next
----

Added
+++++
(... some stuff ...)

Changed
+++++++
- Your line goes here
```
codecov[bot]: # [Codecov](https://codecov.io/gh/glotzerlab/signac/pull/271?src=pr&el=h1) Report
> Merging [#271](https://codecov.io/gh/glotzerlab/signac/pull/271?src=pr&el=desc) into [master](https://codecov.io/gh/glotzerlab/signac/commit/6bf33e097e6545fe7e1d14fddd6e2f35cd23a4bd?src=pr&el=desc) will **decrease** coverage by `<.01%`.
> The diff coverage is `60%`.

[![Impacted file tree graph](https://codecov.io/gh/glotzerlab/signac/pull/271/graphs/tree.svg?width=650&token=FghbjTyzgM&height=150&src=pr)](https://codecov.io/gh/glotzerlab/signac/pull/271?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #271      +/-   ##
==========================================
- Coverage   65.01%   65.01%   -0.01%     
==========================================
  Files          40       40              
  Lines        5626     5631       +5     
==========================================
+ Hits         3658     3661       +3     
- Misses       1968     1970       +2
```


| [Impacted Files](https://codecov.io/gh/glotzerlab/signac/pull/271?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [signac/contrib/project.py](https://codecov.io/gh/glotzerlab/signac/pull/271/diff?src=pr&el=tree#diff-c2lnbmFjL2NvbnRyaWIvcHJvamVjdC5weQ==) | `90.64% <60%> (-0.23%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/glotzerlab/signac/pull/271?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/glotzerlab/signac/pull/271?src=pr&el=footer). Last update [6bf33e0...06bb43a](https://codecov.io/gh/glotzerlab/signac/pull/271?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

diff --git a/changelog.txt b/changelog.txt
index d099ad1a..ac6d84a9 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -14,11 +14,19 @@ Added
 +++++
 
  - Added Windows to platforms tested with continuous integration (#264, #266).
+ 
+Changed
++++++++
+
+ - Workspace directory is created when ``Project`` is initialized (#267, #271).
+
 
 Fixed
 +++++
 
  - Fixed issues on Windows with ``H5Store``, project import/export, and operations that move files (#264, #266).
+ - Calling ``items`` or ``values`` on _SyncedDict objects does not mutate nested dictionaries (#234, #269).
+
 
 
 [1.3.0] -- 2019-12-20
diff --git a/contributors.yaml b/contributors.yaml
index 0838169e..150fa054 100644
--- a/contributors.yaml
+++ b/contributors.yaml
@@ -76,4 +76,8 @@ contributors:
     given-names: Brandon
     affiliation: "University of Michigan"
     orcid: "https://orcid.org/0000-0001-7739-7796"
+  -
+    family-names: Sharma
+    given-names: Vishav
+    affiliation: "National Institute of Technology, Hamirpur"
 ...
diff --git a/signac/contrib/project.py b/signac/contrib/project.py
index 6864be88..208f23a9 100644
--- a/signac/contrib/project.py
+++ b/signac/contrib/project.py
@@ -156,6 +156,16 @@ class Project(object):
         self._fn_doc = os.path.join(self._rd, self.FN_DOCUMENT)
         self._document = None
 
+        # Prepare Workspace Directory
+        if not os.path.isdir(self._wd):
+            try:
+                _mkdir_p(self._wd)
+            except OSError:
+                logger.error(
+                    "Error occurred while trying to create "
+                    "workspace directory for project {}.".format(self.id))
+                raise
+
         # Internal caches
         self._index_cache = dict()
         self._sp_cache = dict()
diff --git a/signac/core/synceddict.py b/signac/core/synceddict.py
index e3eb1393..48c74555 100644
--- a/signac/core/synceddict.py
+++ b/signac/core/synceddict.py
@@ -265,11 +265,11 @@ class _SyncedDict(MutableMapping):
 
     def values(self):
         self._synced_load()
-        return self._convert_to_dict(self._data).values()
+        return self._convert_to_dict(self).values()
 
     def items(self):
         self._synced_load()
-        return self._convert_to_dict(self._data).items()
+        return self._convert_to_dict(self).items()
 
     def __repr__(self):
         return repr(self())
@@ -279,7 +279,7 @@ class _SyncedDict(MutableMapping):
 
     def _as_dict(self):
         with self._suspend_sync():
-            return self._convert_to_dict(self._data.copy())
+            return self._convert_to_dict(self)
 
     def __call__(self):
         self._synced_load()

Fix race condition when workspace is created
### Description

In MPI parallel jobs, where every rank (or every `n` ranks) may initialize a statepoint on the fly, a race condition leads to the job crashing when no `workspace` directory is present. The explanation is that this directory is created on the fly simultaneously by all `job.init()`s of the same ensemble.

A detailed look identifies the `mkdir -p` in https://github.com/glotzerlab/signac/blob/2c0d9e4710bf9a758c53e74a9ad117acc20d43ae/signac/contrib/job.py#L337
as a culprit. The `mkdir` should not include the `-p` option, instead operate only on the target directory. Job workspaces should be created by default upon `signac init`.

Optionally, when they are deleted (for whatever reason), they could be recreated by an explicit `init` call, which would be properly guarded by MPI barriers. For now, the workaround is to create the workspace dir manually.

### To reproduce

```python
sp = {'just': 'a statepoint'}

project = signac.get_project()

# When initializing jobs on the fly in MPI setting:
job = project.open_job(sp)
device.comm.barrier_all() # HOOMD next
if device.comm.partition == 0 and device.comm.rank == 0:
    job.init() # this is the problematic line
device.comm.barrier_all()
```

This would be the suggested way to do it (pending changes to signac):
```python
sp = {'just': 'a statepoint'}

project = signac.get_project()
device.comm.barrier_all()
if device.comm.partition == 0 and device.comm.rank == 0:
    project.init()
device.comm.barrier_all()

# When initializing jobs on the fly in MPI setting:
job = project.open_job(sp)
device.comm.barrier_all()
if device.comm.partition == 0 and device.comm.rank == 0:
    job.init() # this is the problematic line
device.comm.barrier_all()
```
### Error output

If possible, copy any terminal outputs or attach screenshots that provide additional information on the problem.

```
Error occured while trying to create workspace directory for job '42e1468f85f2b689659f23bae00de995'.
State point manifest file of job '42e1468f85f2b689659f23bae00de995' appears to be corrupted.
Traceback (most recent call last):
  File "1brf_umbrella.py", line 125, in <module>
    job.init()
  File "/ccs/home/glaser/.conda/envs/myenv/lib/python3.7/site-packages/signac/contrib/job.py", line 427, in init
    self._init(force=force)
  File "/ccs/home/glaser/.conda/envs/myenv/lib/python3.7/site-packages/signac/contrib/job.py", line 354, in _init
    _mkdir_p(self._wd)
  File "/ccs/home/glaser/.conda/envs/myenv/lib/python3.7/site-packages/signac/contrib/utility.py", line 171, in _mkdir_p
    os.makedirs(path)
  File "/ccs/home/glaser/.conda/envs/myenv/lib/python3.7/os.py", line 221, in makedirs
    mkdir(name, mode)
...
```
### System configuration

Please complete the following information:

 - Operating System [e.g. macOS]: Linux login2 4.14.0-115.8.1.el7a.ppc64le #1 SMP Thu May 9 14:45:13 UTC 2019 ppc64le ppc64le ppc64le GNU/Linux (really, any OS)
 - Version of Python [e.g. 3.7]: Python 3.7.4 (really, any python3 version)
 - Version of signac [e.g. 1.0]: signac 1.0.0 (but looking at the code the problem may also be present in newer versions)

diff --git a/tests/test_project.py b/tests/test_project.py
index 32147f77..f3680f40 100644
--- a/tests/test_project.py
+++ b/tests/test_project.py
@@ -98,6 +98,9 @@ class ProjectTest(BaseProjectTest):
         self.project.config['workspace_dir'] = '${SIGNAC_ENV_DIR_TEST}'
         self.assertEqual(self._tmp_wd, self.project.workspace())
 
+    def test_workspace_directory_exists(self):
+        self.assertTrue(os.path.exists(self.project.workspace()))
+
     def test_fn(self):
         self.assertEqual(
             self.project.fn('test/abc'),
@@ -214,7 +217,8 @@ class ProjectTest(BaseProjectTest):
             norm_path(os.path.join(self.project.root_directory(), self.project.workspace())))
 
     def test_no_workspace_warn_on_find(self):
-        self.assertFalse(os.path.exists(self.project.workspace()))
+        if os.path.exists(self.project.workspace()):
+            os.rmdir(self.project.workspace())
         with self.assertLogs(level='INFO') as cm:
             list(self.project.find_jobs())
             # Python < 3.8 will return 2 messages.
@@ -234,6 +238,8 @@ class ProjectTest(BaseProjectTest):
     def test_workspace_read_only_path(self):
         # Create file where workspace would be, thus preventing the creation
         # of the workspace directory.
+        if os.path.exists(self.project.workspace()):
+            os.rmdir(self.project.workspace())
         with open(os.path.join(self.project.workspace()), 'w'):
             pass
 
diff --git a/tests/test_synced_attrdict.py b/tests/test_synced_attrdict.py
index 503c758d..6509e363 100644
--- a/tests/test_synced_attrdict.py
+++ b/tests/test_synced_attrdict.py
@@ -508,6 +508,18 @@ class SyncedAttrDictTest(unittest.TestCase):
         self.assertEqual(len(sad), 1)
         self.assert_only_read()
 
+    def test_nested_types_dict_conversion(self):
+        """Ensure that calling methods like items and values does not
+        change the type of nested dictionaries."""
+        sad = self.get_sad({'a': {'b': 1}})
+        assert type(sad['a']) is SAD
+        sad.items()
+        assert type(sad['a']) is SAD
+        sad.values()
+        assert type(sad['a']) is SAD
+        sad._as_dict()
+        assert type(sad['a']) is SAD
+
 
 if __name__ == '__main__':
     unittest.main()

pip install -e .[db,h5]
parse_log_pytest
requirements.txt
pymongo passlib bcrypt h5py pytest
3.9
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
bcrypt==4.3.0
deprecation==2.1.0
dnspython==2.7.0
exceptiongroup==1.2.2
filelock==3.18.0
h5py==3.13.0
iniconfig==2.1.0
numpy==2.0.2
packaging==24.2
passlib==1.7.4
pluggy==1.5.0
pymongo==4.11.3
pytest==8.3.5
-e git+https://github.com/glotzerlab/signac.git@dc870ac06159cae97e1475894913d1def567555e#egg=signac
tomli==2.2.1

name: signac
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - bcrypt==4.3.0
      - deprecation==2.1.0
      - dnspython==2.7.0
      - exceptiongroup==1.2.2
      - filelock==3.18.0
      - h5py==3.13.0
      - iniconfig==2.1.0
      - numpy==2.0.2
      - packaging==24.2
      - passlib==1.7.4
      - pluggy==1.5.0
      - pymongo==4.11.3
      - pytest==8.3.5
      - tomli==2.2.1
prefix: /opt/conda/envs/signac

tests/test_project.py::ProjectTest::test_workspace_directory_exists tests/test_project.py::CachedProjectTest::test_workspace_directory_exists tests/test_synced_attrdict.py::SyncedAttrDictTest::test_nested_types_dict_conversion
tests/test_project.py::ProjectTest::test_config_modification tests/test_project.py::ProjectTest::test_corrupted_statepoint_file tests/test_project.py::ProjectTest::test_custom_job_class tests/test_project.py::ProjectTest::test_custom_project tests/test_project.py::ProjectTest::test_data tests/test_project.py::ProjectTest::test_doc tests/test_project.py::ProjectTest::test_document tests/test_project.py::ProjectTest::test_find_job_ids tests/test_project.py::ProjectTest::test_find_jobs tests/test_project.py::ProjectTest::test_find_jobs_arithmetic_operators tests/test_project.py::ProjectTest::test_find_jobs_logical_operators tests/test_project.py::ProjectTest::test_find_jobs_next tests/test_project.py::ProjectTest::test_fn tests/test_project.py::ProjectTest::test_get tests/test_project.py::ProjectTest::test_get_id tests/test_project.py::ProjectTest::test_index tests/test_project.py::ProjectTest::test_isfile tests/test_project.py::ProjectTest::test_iteration tests/test_project.py::ProjectTest::test_job_clone tests/test_project.py::ProjectTest::test_job_move tests/test_project.py::ProjectTest::test_jobs_groupby tests/test_project.py::ProjectTest::test_jobs_groupbydoc tests/test_project.py::ProjectTest::test_len_find_jobs tests/test_project.py::ProjectTest::test_missing_statepoint_file tests/test_project.py::ProjectTest::test_no_workspace_warn_on_find tests/test_project.py::ProjectTest::test_num_jobs tests/test_project.py::ProjectTest::test_open_job_by_abbreviated_id tests/test_project.py::ProjectTest::test_open_job_by_id tests/test_project.py::ProjectTest::test_project_contains tests/test_project.py::ProjectTest::test_property_id tests/test_project.py::ProjectTest::test_rename_workspace tests/test_project.py::ProjectTest::test_repair_corrupted_workspace tests/test_project.py::ProjectTest::test_repr tests/test_project.py::ProjectTest::test_root_directory tests/test_project.py::ProjectTest::test_schema tests/test_project.py::ProjectTest::test_schema_difference tests/test_project.py::ProjectTest::test_schema_eval tests/test_project.py::ProjectTest::test_schema_init tests/test_project.py::ProjectTest::test_schema_subset tests/test_project.py::ProjectTest::test_signac_project_crawler tests/test_project.py::ProjectTest::test_str tests/test_project.py::ProjectTest::test_temp_project tests/test_project.py::ProjectTest::test_workspace_broken_link_error_on_find tests/test_project.py::ProjectTest::test_workspace_directory tests/test_project.py::ProjectTest::test_workspace_directory_with_env_variable tests/test_project.py::ProjectTest::test_workspace_path_normalization tests/test_project.py::ProjectTest::test_workspace_read_only_path tests/test_project.py::ProjectTest::test_write_read_statepoint tests/test_project.py::ProjectExportImportTest::test_export tests/test_project.py::ProjectExportImportTest::test_export_custom_path_function tests/test_project.py::ProjectExportImportTest::test_export_custom_path_function_move tests/test_project.py::ProjectExportImportTest::test_export_custom_path_string tests/test_project.py::ProjectExportImportTest::test_export_custom_path_string_modify_flat_flat tests/test_project.py::ProjectExportImportTest::test_export_custom_path_string_modify_flat_tree tests/test_project.py::ProjectExportImportTest::test_export_custom_path_string_modify_tree_flat tests/test_project.py::ProjectExportImportTest::test_export_custom_path_string_modify_tree_tree tests/test_project.py::ProjectExportImportTest::test_export_import tests/test_project.py::ProjectExportImportTest::test_export_import_complex_path tests/test_project.py::ProjectExportImportTest::test_export_import_complex_path_nested_schema_from_path tests/test_project.py::ProjectExportImportTest::test_export_import_conflict tests/test_project.py::ProjectExportImportTest::test_export_import_conflict_synced tests/test_project.py::ProjectExportImportTest::test_export_import_conflict_synced_with_args tests/test_project.py::ProjectExportImportTest::test_export_import_schema_callable tests/test_project.py::ProjectExportImportTest::test_export_import_schema_callable_non_unique tests/test_project.py::ProjectExportImportTest::test_export_import_simple_path tests/test_project.py::ProjectExportImportTest::test_export_import_simple_path_nested_with_schema tests/test_project.py::ProjectExportImportTest::test_export_import_simple_path_schema_from_path tests/test_project.py::ProjectExportImportTest::test_export_import_simple_path_schema_from_path_float tests/test_project.py::ProjectExportImportTest::test_export_import_simple_path_with_float tests/test_project.py::ProjectExportImportTest::test_export_import_tarfile tests/test_project.py::ProjectExportImportTest::test_export_import_tarfile_zipped tests/test_project.py::ProjectExportImportTest::test_export_import_tarfile_zipped_longname tests/test_project.py::ProjectExportImportTest::test_export_import_zipfile tests/test_project.py::ProjectExportImportTest::test_export_move tests/test_project.py::ProjectExportImportTest::test_export_single_job tests/test_project.py::ProjectExportImportTest::test_import_own_project tests/test_project.py::LinkedViewProjectTest::test_create_linked_view tests/test_project.py::LinkedViewProjectTest::test_create_linked_view_heterogeneous_disjoint_schema tests/test_project.py::LinkedViewProjectTest::test_create_linked_view_heterogeneous_disjoint_schema_nested tests/test_project.py::LinkedViewProjectTest::test_create_linked_view_heterogeneous_fizz_schema_flat tests/test_project.py::LinkedViewProjectTest::test_create_linked_view_heterogeneous_schema_nested tests/test_project.py::LinkedViewProjectTest::test_create_linked_view_heterogeneous_schema_nested_partial_homogenous_path_provide tests/test_project.py::LinkedViewProjectTest::test_create_linked_view_heterogeneous_schema_problematic tests/test_project.py::LinkedViewProjectTest::test_create_linked_view_homogeneous_schema_flat_flat tests/test_project.py::LinkedViewProjectTest::test_create_linked_view_homogeneous_schema_flat_tree tests/test_project.py::LinkedViewProjectTest::test_create_linked_view_homogeneous_schema_nested tests/test_project.py::LinkedViewProjectTest::test_create_linked_view_homogeneous_schema_nested_provide_partial_path tests/test_project.py::LinkedViewProjectTest::test_create_linked_view_homogeneous_schema_tree tests/test_project.py::LinkedViewProjectTest::test_create_linked_view_homogeneous_schema_tree_flat tests/test_project.py::LinkedViewProjectTest::test_create_linked_view_homogeneous_schema_tree_tree tests/test_project.py::LinkedViewProjectTest::test_create_linked_view_with_slash_raises_error tests/test_project.py::CachedProjectTest::test_config_modification tests/test_project.py::CachedProjectTest::test_corrupted_statepoint_file tests/test_project.py::CachedProjectTest::test_custom_job_class tests/test_project.py::CachedProjectTest::test_custom_project tests/test_project.py::CachedProjectTest::test_data tests/test_project.py::CachedProjectTest::test_doc tests/test_project.py::CachedProjectTest::test_document tests/test_project.py::CachedProjectTest::test_find_job_ids tests/test_project.py::CachedProjectTest::test_find_jobs tests/test_project.py::CachedProjectTest::test_find_jobs_arithmetic_operators tests/test_project.py::CachedProjectTest::test_find_jobs_logical_operators tests/test_project.py::CachedProjectTest::test_find_jobs_next tests/test_project.py::CachedProjectTest::test_fn tests/test_project.py::CachedProjectTest::test_get tests/test_project.py::CachedProjectTest::test_get_id tests/test_project.py::CachedProjectTest::test_index tests/test_project.py::CachedProjectTest::test_isfile tests/test_project.py::CachedProjectTest::test_iteration tests/test_project.py::CachedProjectTest::test_job_clone tests/test_project.py::CachedProjectTest::test_job_move tests/test_project.py::CachedProjectTest::test_jobs_groupby tests/test_project.py::CachedProjectTest::test_jobs_groupbydoc tests/test_project.py::CachedProjectTest::test_len_find_jobs tests/test_project.py::CachedProjectTest::test_missing_statepoint_file tests/test_project.py::CachedProjectTest::test_no_workspace_warn_on_find tests/test_project.py::CachedProjectTest::test_num_jobs tests/test_project.py::CachedProjectTest::test_open_job_by_abbreviated_id tests/test_project.py::CachedProjectTest::test_open_job_by_id tests/test_project.py::CachedProjectTest::test_project_contains tests/test_project.py::CachedProjectTest::test_property_id tests/test_project.py::CachedProjectTest::test_rename_workspace tests/test_project.py::CachedProjectTest::test_repair_corrupted_workspace tests/test_project.py::CachedProjectTest::test_repr tests/test_project.py::CachedProjectTest::test_root_directory tests/test_project.py::CachedProjectTest::test_schema tests/test_project.py::CachedProjectTest::test_schema_difference tests/test_project.py::CachedProjectTest::test_schema_eval tests/test_project.py::CachedProjectTest::test_schema_init tests/test_project.py::CachedProjectTest::test_schema_subset tests/test_project.py::CachedProjectTest::test_signac_project_crawler tests/test_project.py::CachedProjectTest::test_str tests/test_project.py::CachedProjectTest::test_temp_project tests/test_project.py::CachedProjectTest::test_workspace_broken_link_error_on_find tests/test_project.py::CachedProjectTest::test_workspace_directory tests/test_project.py::CachedProjectTest::test_workspace_directory_with_env_variable tests/test_project.py::CachedProjectTest::test_workspace_path_normalization tests/test_project.py::CachedProjectTest::test_workspace_read_only_path tests/test_project.py::CachedProjectTest::test_write_read_statepoint tests/test_project.py::ProjectInitTest::test_get_job_invalid_workspace tests/test_project.py::ProjectInitTest::test_get_job_nested_project tests/test_project.py::ProjectInitTest::test_get_job_nested_project_subdir tests/test_project.py::ProjectInitTest::test_get_job_subdir tests/test_project.py::ProjectInitTest::test_get_job_symlink_other_project tests/test_project.py::ProjectInitTest::test_get_job_valid_workspace tests/test_project.py::ProjectInitTest::test_get_project tests/test_project.py::ProjectInitTest::test_get_project_all_printable_characters tests/test_project.py::ProjectInitTest::test_get_project_non_local tests/test_project.py::ProjectInitTest::test_init tests/test_project.py::ProjectInitTest::test_nested_project tests/test_project.py::ProjectSchemaTest::test_no_migration tests/test_project.py::ProjectSchemaTest::test_project_schema_version_migration tests/test_project.py::ProjectSchemaTest::test_project_schema_versions tests/test_project.py::ProjectPicklingTest::test_pickle_jobs_directly tests/test_project.py::ProjectPicklingTest::test_pickle_project_empty tests/test_project.py::ProjectPicklingTest::test_pickle_project_with_jobs tests/test_project.py::TestTestingProjectInitialization::test_input_args tests/test_synced_attrdict.py::SyncedAttrDictTest::test_attr_reference_modification tests/test_synced_attrdict.py::SyncedAttrDictTest::test_call tests/test_synced_attrdict.py::SyncedAttrDictTest::test_clear tests/test_synced_attrdict.py::SyncedAttrDictTest::test_clear_sync tests/test_synced_attrdict.py::SyncedAttrDictTest::test_copy tests/test_synced_attrdict.py::SyncedAttrDictTest::test_copy_as_dict tests/test_synced_attrdict.py::SyncedAttrDictTest::test_copy_as_dict_sync tests/test_synced_attrdict.py::SyncedAttrDictTest::test_copy_value tests/test_synced_attrdict.py::SyncedAttrDictTest::test_delete tests/test_synced_attrdict.py::SyncedAttrDictTest::test_delete_sync tests/test_synced_attrdict.py::SyncedAttrDictTest::test_init tests/test_synced_attrdict.py::SyncedAttrDictTest::test_is_object_and_mapping tests/test_synced_attrdict.py::SyncedAttrDictTest::test_iter tests/test_synced_attrdict.py::SyncedAttrDictTest::test_iter_sync tests/test_synced_attrdict.py::SyncedAttrDictTest::test_list_modification tests/test_synced_attrdict.py::SyncedAttrDictTest::test_repr tests/test_synced_attrdict.py::SyncedAttrDictTest::test_set_get tests/test_synced_attrdict.py::SyncedAttrDictTest::test_set_get_attr_sync tests/test_synced_attrdict.py::SyncedAttrDictTest::test_set_get_explicit_nested tests/test_synced_attrdict.py::SyncedAttrDictTest::test_set_get_sync tests/test_synced_attrdict.py::SyncedAttrDictTest::test_str tests/test_synced_attrdict.py::SyncedAttrDictTest::test_suspend_sync tests/test_synced_attrdict.py::SyncedAttrDictTest::test_update tests/test_synced_attrdict.py::SyncedAttrDictTest::test_update_sync
signac/contrib/project.py signac/core/synceddict.py contributors.yaml changelog.txt
signac/contrib/project.py signac/core/synceddict.py contributors.yaml changelog.txt