From 45e802d4d4f4a81dd540b4a9c72855a6e4ecf3c5 Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Sat, 5 Mar 2022 10:20:08 -0800 Subject: [PATCH] Change Project constructor to use root directory (#706) * Change project constructor to accept a root directory instead of a config file. * Change Project repr. * Address easy PR comments. --- signac/contrib/project.py | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/signac/contrib/project.py b/signac/contrib/project.py index d705475d8..8c367d914 100644 --- a/signac/contrib/project.py +++ b/signac/contrib/project.py @@ -106,16 +106,17 @@ def __setitem__(self, key, value): class Project: """The handle on a signac project. - Application developers should usually not need to - directly instantiate this class, but use - :meth:`~signac.get_project` instead. + A :class:`Project` may only be constructed in a directory that is already a + signac project, i.e. a directory in which :func:`~signac.init_project` has + already been run. If project discovery (searching upwards in the folder + hierarchy until a project root is discovered) is desired, users should + instead invoke :func:`~signac.get_project` or :meth:`Project.get_project`. Parameters ---------- - config : - The project configuration to use. By default, it loads the first signac - project configuration found while searching upward from the current - working directory (Default value = None). + root : str, optional + The project root directory. By default, the current working directory + (Default value = None). """ @@ -130,9 +131,12 @@ class Project: _use_pandas_for_html_repr = True # toggle use of pandas for html repr - def __init__(self, config=None): - if config is None: - config = load_config() + def __init__(self, root=None): + if root is None: + root = os.getcwd() + # Project constructor does not search upward, so the provided root must + # be a project directory. + config = load_config(root, local=True) self._config = _ProjectConfig(config) self._lock = RLock() @@ -183,9 +187,7 @@ def __str__(self): return str(self.root_directory()) def __repr__(self): - return "{type}.get_project({root})".format( - type=self.__class__.__name__, root=repr(self.root_directory()) - ) + return f"{self.__class__.__name__}({repr(self.root_directory())})" def _repr_html_(self): """Project details in HTML format for use in IPython environment. @@ -1625,7 +1627,7 @@ def get_project(cls, root=None, search=True, **kwargs): f"Unable to determine project id for nonexistent path '{os.path.abspath(root)}'." ) - config = load_config(root=root, local=False) + config = load_config(root=root, local=not search) if "project_dir" not in config or ( not search and os.path.realpath(config["project_dir"]) != os.path.realpath(root) @@ -1634,7 +1636,7 @@ def get_project(cls, root=None, search=True, **kwargs): f"Unable to determine project id for path '{os.path.abspath(root)}'." ) - return cls(config=config, **kwargs) + return cls(root=config["project_dir"], **kwargs) @classmethod def get_job(cls, root=None):