edq.config.source
1import os 2import typing 3 4import edq.config.common 5import edq.util.serial 6 7class ConfigSourceSpec(edq.config.common.InternalConfigSourceSpec): 8 """ 9 A source spec represents a location where config values may be stored. 10 """ 11 12class CLIExplicitSpec(ConfigSourceSpec): 13 """ 14 A source spec for loading from CLI arguments (but not files specified on the command-line). 15 Explicit refers to arguments that are explicitly noted with the `--config` flag. 16 """ 17 18 label: str = 'cli argument (explicit)' 19 20 def get_help_lines(self) -> typing.List[str]: 21 return [ 22 'Command-Line Arguments (Explicit)', 23 'Load configuration values set directly on the command-line via the `--config` flag.', 24 '"Explicit" refers to the fact that these arguments use the `--config` flag.', 25 'Multiple instances may be supplied, and they will be processed in the order provided.', 26 ] 27 28class CLIImplicitSpec(ConfigSourceSpec): 29 """ 30 A source spec for loading from CLI arguments (but not files specified on the command-line). 31 Implicit refers to arguments that are not explicitly supplied with the `--config` flag, 32 and instead specified with other flags. 33 For example, a CLI may accept a `--server` flag that sets a `server` argument. 34 """ 35 36 37 label: str = 'cli argument (implicit)' 38 39 def get_help_lines(self) -> typing.List[str]: 40 return [ 41 'Command-Line Arguments (Implicit)', 42 'Load configuration values set directly on the command-line.', 43 '"Implicit" refers to the fact that these arguments do not use the `--config` flag.', 44 'Multiple instances may be supplied, and they will be processed in the order provided.', 45 'Default values from implicit command-line arguments will not override previously set values.', 46 ] 47 48class CLIFileSpec(ConfigSourceSpec): 49 """ A source spec for loading a file that was specified as a CLI argument. """ 50 51 label: str = 'cli config file' 52 53 def get_help_lines(self) -> typing.List[str]: 54 return [ 55 'Command-Line Files', 56 'Load configuration files specified on the command-line via the `--config-file` flag.', 57 'Multiple instances may be supplied, and they will be processed in the order provided.', 58 ] 59 60class ENVSpec(ConfigSourceSpec): 61 """ A source spec for loading from an environmental variable. """ 62 63 label: str = 'environmental variable' 64 65 def get_help_lines(self) -> typing.List[str]: 66 return [ 67 'Environmental Variables', 68 'Load configuration values specified in environmental variables.', 69 f"Variable names must start with the prefix: '{edq.config.common._env_prefix}'.", 70 'Variable names will be stripped of the above prefix and turned to lower case.', 71 ] 72 73class AbstractPathSpec(ConfigSourceSpec): 74 """ 75 An abstract source spec that includes a target directory and filename. 76 77 An argument not set (or set to None) indicates that the value should be determined at parse time. 78 These values (generally paths or filenames) are often pulled from the `edq.config.settings` module 79 (and therefore can be set by users of this library anytime before loading the config). 80 """ 81 82 def __init__(self, 83 base_dir: typing.Union[str, None] = None, 84 filename: typing.Union[str, None] = None, 85 **kwargs: typing.Any) -> None: 86 super().__init__() 87 88 if ((base_dir is not None) and (os.path.isfile(base_dir))): 89 raise ValueError(f"The specified config dir is not a directory: '{base_dir}'.") 90 91 self.base_dir: typing.Union[str, None] = base_dir 92 """ The directory to look for the global config file in. """ 93 94 self.filename: typing.Union[str, None] = filename 95 """ The filename to look for. """ 96 97 def get_base_dir(self) -> typing.Union[str, None]: 98 """ Get the base dir for this spec. """ 99 100 if (self.base_dir is not None): 101 return self.base_dir 102 103 return self.get_default_base_dir() 104 105 def get_filename(self) -> typing.Union[str, None]: 106 """ Get the filename for this spec. """ 107 108 if (self.filename is not None): 109 return self.filename 110 111 return self.get_default_filename() 112 113 def get_default_base_dir(self) -> typing.Union[str, None]: 114 """ Retrieve the default base dir (usually from edq.config.settings) for use when no base dir is explicitly set. """ 115 116 return None 117 118 def get_default_filename(self) -> typing.Union[str, None]: 119 """ Retrieve the default filename (usually from edq.config.settings) for use when no filename is explicitly set. """ 120 121 return None 122 123 def resolve_path(self, 124 override_path: typing.Union[str, None] = None, 125 ) -> str: 126 """ 127 Get the path that should be use to load config. 128 This method is free to traverse the disk to find the desired path. 129 """ 130 131 if (override_path is not None): 132 return override_path 133 134 base_dir = self.get_base_dir() 135 if (base_dir is None): 136 raise ValueError(f"Unable to resolve a config base dir for class {type(self)}.") 137 138 filename = self.get_filename() 139 if (filename is None): 140 raise ValueError(f"Unable to resolve a config filename for class {type(self)}.") 141 142 return os.path.join(base_dir, filename) 143 144class GlobalSpec(AbstractPathSpec): 145 """ A source spec for loading from a global (user-level) config file. """ 146 147 label: str = 'global config file' 148 149 def get_help_lines(self) -> typing.List[str]: 150 return [ 151 'Global Config File', 152 'Load configurations from a "global" config file (e.g., a file that stays the same for a specific user).', 153 'This file is a good location for configuration values that do not change from project to project,', 154 'such as usernames and passwords/tokens.', 155 f"For this machine and user, the global config is located at: '{self.resolve_path()}'.", 156 ] 157 158 def get_default_base_dir(self) -> typing.Union[str, None]: 159 return edq.config.common._global_dir 160 161 def get_default_filename(self) -> typing.Union[str, None]: 162 return edq.config.common._config_filename 163 164class LocalSpec(AbstractPathSpec): 165 """ A source spec for loading from a local config file. """ 166 167 label: str = 'local config file' 168 169 def get_help_lines(self) -> typing.List[str]: 170 return [ 171 'Local Config File', 172 'Load configurations from a "local" config file inside of the current directory.', 173 f"The file must be named: '{self.get_filename()}'.", 174 ] 175 176 def get_default_base_dir(self) -> typing.Union[str, None]: 177 return os.path.abspath(os.getcwd()) 178 179 def get_default_filename(self) -> typing.Union[str, None]: 180 return edq.config.common._config_filename 181 182class ProjectSpec(AbstractPathSpec): 183 """ 184 A source spec for loading from a project, which will look in the current directory and all parents until a matching file is found. 185 """ 186 187 label: str = 'project config file' 188 189 def get_help_lines(self) -> typing.List[str]: 190 return [ 191 'Project Config File', 192 'Load configurations from a "project" config file.', 193 'To find a project configuration file, we will look in the current directory and all parents (until root).', 194 'The first file found with the correct name will be loaded.', 195 'It is recommended to keep this file in your project\'s root directory.', 196 'This allows you to execute commands from anywhere in the project using the correct configuration settings.', 197 f"The file must be named: '{self.get_filename()}'.", 198 ] 199 200 def __init__(self, 201 root_cutoff: typing.Union[str, None] = None, 202 filename: typing.Union[str, None] = None, 203 **kwargs: typing.Any) -> None: 204 super().__init__(**kwargs) 205 206 self.root_cutoff: typing.Union[str, None] = root_cutoff 207 """ If set, stop searching parents if this directory is encountered. """ 208 209 def get_default_base_dir(self) -> typing.Union[str, None]: 210 return os.path.abspath(os.getcwd()) 211 212 def get_default_filename(self) -> typing.Union[str, None]: 213 return edq.config.common._config_filename 214 215 def resolve_path(self, 216 override_path: typing.Union[str, None] = None, 217 ) -> str: 218 if (override_path is not None): 219 return override_path 220 221 base_dir = self.get_base_dir() 222 if (base_dir is None): 223 raise ValueError(f"Unable to resolve a config base dir for class {type(self)}.") 224 225 filename = self.get_filename() 226 if (filename is None): 227 raise ValueError(f"Unable to resolve a config filename for class {type(self)}.") 228 229 current_dir = base_dir 230 for _ in range(edq.util.dirent.DEPTH_LIMIT): 231 path = os.path.join(current_dir, filename) 232 if (os.path.isfile(path)): 233 return path 234 235 # Check if current directory is root. 236 parent_dir = os.path.dirname(current_dir) 237 if (parent_dir == current_dir): 238 break 239 240 if ((self.root_cutoff is not None) and (self.root_cutoff == current_dir)): 241 break 242 243 current_dir = parent_dir 244 245 # If no file was found, use the base dir. 246 return os.path.join(base_dir, filename) 247 248edq.config.common._DEFAULT_LOAD_ORDER = [ 249 GlobalSpec(), 250 ProjectSpec(), 251 ENVSpec(), 252 CLIFileSpec(), 253 CLIImplicitSpec(), 254 CLIExplicitSpec(), 255] 256edq.config.common._load_order = edq.config.common._DEFAULT_LOAD_ORDER.copy()
8class ConfigSourceSpec(edq.config.common.InternalConfigSourceSpec): 9 """ 10 A source spec represents a location where config values may be stored. 11 """
A source spec represents a location where config values may be stored.
Inherited Members
13class CLIExplicitSpec(ConfigSourceSpec): 14 """ 15 A source spec for loading from CLI arguments (but not files specified on the command-line). 16 Explicit refers to arguments that are explicitly noted with the `--config` flag. 17 """ 18 19 label: str = 'cli argument (explicit)' 20 21 def get_help_lines(self) -> typing.List[str]: 22 return [ 23 'Command-Line Arguments (Explicit)', 24 'Load configuration values set directly on the command-line via the `--config` flag.', 25 '"Explicit" refers to the fact that these arguments use the `--config` flag.', 26 'Multiple instances may be supplied, and they will be processed in the order provided.', 27 ]
A source spec for loading from CLI arguments (but not files specified on the command-line).
Explicit refers to arguments that are explicitly noted with the --config flag.
A label set by each subclass to identify the type of source spec. Generally, a user-friendly version of the class name.
21 def get_help_lines(self) -> typing.List[str]: 22 return [ 23 'Command-Line Arguments (Explicit)', 24 'Load configuration values set directly on the command-line via the `--config` flag.', 25 '"Explicit" refers to the fact that these arguments use the `--config` flag.', 26 'Multiple instances may be supplied, and they will be processed in the order provided.', 27 ]
Get lines of text describing how this source is loaded. This text is intended to be used in a help prompt.
Inherited Members
29class CLIImplicitSpec(ConfigSourceSpec): 30 """ 31 A source spec for loading from CLI arguments (but not files specified on the command-line). 32 Implicit refers to arguments that are not explicitly supplied with the `--config` flag, 33 and instead specified with other flags. 34 For example, a CLI may accept a `--server` flag that sets a `server` argument. 35 """ 36 37 38 label: str = 'cli argument (implicit)' 39 40 def get_help_lines(self) -> typing.List[str]: 41 return [ 42 'Command-Line Arguments (Implicit)', 43 'Load configuration values set directly on the command-line.', 44 '"Implicit" refers to the fact that these arguments do not use the `--config` flag.', 45 'Multiple instances may be supplied, and they will be processed in the order provided.', 46 'Default values from implicit command-line arguments will not override previously set values.', 47 ]
A source spec for loading from CLI arguments (but not files specified on the command-line).
Implicit refers to arguments that are not explicitly supplied with the --config flag,
and instead specified with other flags.
For example, a CLI may accept a --server flag that sets a server argument.
A label set by each subclass to identify the type of source spec. Generally, a user-friendly version of the class name.
40 def get_help_lines(self) -> typing.List[str]: 41 return [ 42 'Command-Line Arguments (Implicit)', 43 'Load configuration values set directly on the command-line.', 44 '"Implicit" refers to the fact that these arguments do not use the `--config` flag.', 45 'Multiple instances may be supplied, and they will be processed in the order provided.', 46 'Default values from implicit command-line arguments will not override previously set values.', 47 ]
Get lines of text describing how this source is loaded. This text is intended to be used in a help prompt.
Inherited Members
49class CLIFileSpec(ConfigSourceSpec): 50 """ A source spec for loading a file that was specified as a CLI argument. """ 51 52 label: str = 'cli config file' 53 54 def get_help_lines(self) -> typing.List[str]: 55 return [ 56 'Command-Line Files', 57 'Load configuration files specified on the command-line via the `--config-file` flag.', 58 'Multiple instances may be supplied, and they will be processed in the order provided.', 59 ]
A source spec for loading a file that was specified as a CLI argument.
A label set by each subclass to identify the type of source spec. Generally, a user-friendly version of the class name.
54 def get_help_lines(self) -> typing.List[str]: 55 return [ 56 'Command-Line Files', 57 'Load configuration files specified on the command-line via the `--config-file` flag.', 58 'Multiple instances may be supplied, and they will be processed in the order provided.', 59 ]
Get lines of text describing how this source is loaded. This text is intended to be used in a help prompt.
Inherited Members
61class ENVSpec(ConfigSourceSpec): 62 """ A source spec for loading from an environmental variable. """ 63 64 label: str = 'environmental variable' 65 66 def get_help_lines(self) -> typing.List[str]: 67 return [ 68 'Environmental Variables', 69 'Load configuration values specified in environmental variables.', 70 f"Variable names must start with the prefix: '{edq.config.common._env_prefix}'.", 71 'Variable names will be stripped of the above prefix and turned to lower case.', 72 ]
A source spec for loading from an environmental variable.
A label set by each subclass to identify the type of source spec. Generally, a user-friendly version of the class name.
66 def get_help_lines(self) -> typing.List[str]: 67 return [ 68 'Environmental Variables', 69 'Load configuration values specified in environmental variables.', 70 f"Variable names must start with the prefix: '{edq.config.common._env_prefix}'.", 71 'Variable names will be stripped of the above prefix and turned to lower case.', 72 ]
Get lines of text describing how this source is loaded. This text is intended to be used in a help prompt.
Inherited Members
74class AbstractPathSpec(ConfigSourceSpec): 75 """ 76 An abstract source spec that includes a target directory and filename. 77 78 An argument not set (or set to None) indicates that the value should be determined at parse time. 79 These values (generally paths or filenames) are often pulled from the `edq.config.settings` module 80 (and therefore can be set by users of this library anytime before loading the config). 81 """ 82 83 def __init__(self, 84 base_dir: typing.Union[str, None] = None, 85 filename: typing.Union[str, None] = None, 86 **kwargs: typing.Any) -> None: 87 super().__init__() 88 89 if ((base_dir is not None) and (os.path.isfile(base_dir))): 90 raise ValueError(f"The specified config dir is not a directory: '{base_dir}'.") 91 92 self.base_dir: typing.Union[str, None] = base_dir 93 """ The directory to look for the global config file in. """ 94 95 self.filename: typing.Union[str, None] = filename 96 """ The filename to look for. """ 97 98 def get_base_dir(self) -> typing.Union[str, None]: 99 """ Get the base dir for this spec. """ 100 101 if (self.base_dir is not None): 102 return self.base_dir 103 104 return self.get_default_base_dir() 105 106 def get_filename(self) -> typing.Union[str, None]: 107 """ Get the filename for this spec. """ 108 109 if (self.filename is not None): 110 return self.filename 111 112 return self.get_default_filename() 113 114 def get_default_base_dir(self) -> typing.Union[str, None]: 115 """ Retrieve the default base dir (usually from edq.config.settings) for use when no base dir is explicitly set. """ 116 117 return None 118 119 def get_default_filename(self) -> typing.Union[str, None]: 120 """ Retrieve the default filename (usually from edq.config.settings) for use when no filename is explicitly set. """ 121 122 return None 123 124 def resolve_path(self, 125 override_path: typing.Union[str, None] = None, 126 ) -> str: 127 """ 128 Get the path that should be use to load config. 129 This method is free to traverse the disk to find the desired path. 130 """ 131 132 if (override_path is not None): 133 return override_path 134 135 base_dir = self.get_base_dir() 136 if (base_dir is None): 137 raise ValueError(f"Unable to resolve a config base dir for class {type(self)}.") 138 139 filename = self.get_filename() 140 if (filename is None): 141 raise ValueError(f"Unable to resolve a config filename for class {type(self)}.") 142 143 return os.path.join(base_dir, filename)
An abstract source spec that includes a target directory and filename.
An argument not set (or set to None) indicates that the value should be determined at parse time.
These values (generally paths or filenames) are often pulled from the edq.config.settings module
(and therefore can be set by users of this library anytime before loading the config).
98 def get_base_dir(self) -> typing.Union[str, None]: 99 """ Get the base dir for this spec. """ 100 101 if (self.base_dir is not None): 102 return self.base_dir 103 104 return self.get_default_base_dir()
Get the base dir for this spec.
106 def get_filename(self) -> typing.Union[str, None]: 107 """ Get the filename for this spec. """ 108 109 if (self.filename is not None): 110 return self.filename 111 112 return self.get_default_filename()
Get the filename for this spec.
114 def get_default_base_dir(self) -> typing.Union[str, None]: 115 """ Retrieve the default base dir (usually from edq.config.settings) for use when no base dir is explicitly set. """ 116 117 return None
Retrieve the default base dir (usually from edq.config.settings) for use when no base dir is explicitly set.
119 def get_default_filename(self) -> typing.Union[str, None]: 120 """ Retrieve the default filename (usually from edq.config.settings) for use when no filename is explicitly set. """ 121 122 return None
Retrieve the default filename (usually from edq.config.settings) for use when no filename is explicitly set.
124 def resolve_path(self, 125 override_path: typing.Union[str, None] = None, 126 ) -> str: 127 """ 128 Get the path that should be use to load config. 129 This method is free to traverse the disk to find the desired path. 130 """ 131 132 if (override_path is not None): 133 return override_path 134 135 base_dir = self.get_base_dir() 136 if (base_dir is None): 137 raise ValueError(f"Unable to resolve a config base dir for class {type(self)}.") 138 139 filename = self.get_filename() 140 if (filename is None): 141 raise ValueError(f"Unable to resolve a config filename for class {type(self)}.") 142 143 return os.path.join(base_dir, filename)
Get the path that should be use to load config. This method is free to traverse the disk to find the desired path.
Inherited Members
145class GlobalSpec(AbstractPathSpec): 146 """ A source spec for loading from a global (user-level) config file. """ 147 148 label: str = 'global config file' 149 150 def get_help_lines(self) -> typing.List[str]: 151 return [ 152 'Global Config File', 153 'Load configurations from a "global" config file (e.g., a file that stays the same for a specific user).', 154 'This file is a good location for configuration values that do not change from project to project,', 155 'such as usernames and passwords/tokens.', 156 f"For this machine and user, the global config is located at: '{self.resolve_path()}'.", 157 ] 158 159 def get_default_base_dir(self) -> typing.Union[str, None]: 160 return edq.config.common._global_dir 161 162 def get_default_filename(self) -> typing.Union[str, None]: 163 return edq.config.common._config_filename
A source spec for loading from a global (user-level) config file.
A label set by each subclass to identify the type of source spec. Generally, a user-friendly version of the class name.
150 def get_help_lines(self) -> typing.List[str]: 151 return [ 152 'Global Config File', 153 'Load configurations from a "global" config file (e.g., a file that stays the same for a specific user).', 154 'This file is a good location for configuration values that do not change from project to project,', 155 'such as usernames and passwords/tokens.', 156 f"For this machine and user, the global config is located at: '{self.resolve_path()}'.", 157 ]
Get lines of text describing how this source is loaded. This text is intended to be used in a help prompt.
159 def get_default_base_dir(self) -> typing.Union[str, None]: 160 return edq.config.common._global_dir
Retrieve the default base dir (usually from edq.config.settings) for use when no base dir is explicitly set.
162 def get_default_filename(self) -> typing.Union[str, None]: 163 return edq.config.common._config_filename
Retrieve the default filename (usually from edq.config.settings) for use when no filename is explicitly set.
Inherited Members
165class LocalSpec(AbstractPathSpec): 166 """ A source spec for loading from a local config file. """ 167 168 label: str = 'local config file' 169 170 def get_help_lines(self) -> typing.List[str]: 171 return [ 172 'Local Config File', 173 'Load configurations from a "local" config file inside of the current directory.', 174 f"The file must be named: '{self.get_filename()}'.", 175 ] 176 177 def get_default_base_dir(self) -> typing.Union[str, None]: 178 return os.path.abspath(os.getcwd()) 179 180 def get_default_filename(self) -> typing.Union[str, None]: 181 return edq.config.common._config_filename
A source spec for loading from a local config file.
A label set by each subclass to identify the type of source spec. Generally, a user-friendly version of the class name.
170 def get_help_lines(self) -> typing.List[str]: 171 return [ 172 'Local Config File', 173 'Load configurations from a "local" config file inside of the current directory.', 174 f"The file must be named: '{self.get_filename()}'.", 175 ]
Get lines of text describing how this source is loaded. This text is intended to be used in a help prompt.
177 def get_default_base_dir(self) -> typing.Union[str, None]: 178 return os.path.abspath(os.getcwd())
Retrieve the default base dir (usually from edq.config.settings) for use when no base dir is explicitly set.
180 def get_default_filename(self) -> typing.Union[str, None]: 181 return edq.config.common._config_filename
Retrieve the default filename (usually from edq.config.settings) for use when no filename is explicitly set.
Inherited Members
183class ProjectSpec(AbstractPathSpec): 184 """ 185 A source spec for loading from a project, which will look in the current directory and all parents until a matching file is found. 186 """ 187 188 label: str = 'project config file' 189 190 def get_help_lines(self) -> typing.List[str]: 191 return [ 192 'Project Config File', 193 'Load configurations from a "project" config file.', 194 'To find a project configuration file, we will look in the current directory and all parents (until root).', 195 'The first file found with the correct name will be loaded.', 196 'It is recommended to keep this file in your project\'s root directory.', 197 'This allows you to execute commands from anywhere in the project using the correct configuration settings.', 198 f"The file must be named: '{self.get_filename()}'.", 199 ] 200 201 def __init__(self, 202 root_cutoff: typing.Union[str, None] = None, 203 filename: typing.Union[str, None] = None, 204 **kwargs: typing.Any) -> None: 205 super().__init__(**kwargs) 206 207 self.root_cutoff: typing.Union[str, None] = root_cutoff 208 """ If set, stop searching parents if this directory is encountered. """ 209 210 def get_default_base_dir(self) -> typing.Union[str, None]: 211 return os.path.abspath(os.getcwd()) 212 213 def get_default_filename(self) -> typing.Union[str, None]: 214 return edq.config.common._config_filename 215 216 def resolve_path(self, 217 override_path: typing.Union[str, None] = None, 218 ) -> str: 219 if (override_path is not None): 220 return override_path 221 222 base_dir = self.get_base_dir() 223 if (base_dir is None): 224 raise ValueError(f"Unable to resolve a config base dir for class {type(self)}.") 225 226 filename = self.get_filename() 227 if (filename is None): 228 raise ValueError(f"Unable to resolve a config filename for class {type(self)}.") 229 230 current_dir = base_dir 231 for _ in range(edq.util.dirent.DEPTH_LIMIT): 232 path = os.path.join(current_dir, filename) 233 if (os.path.isfile(path)): 234 return path 235 236 # Check if current directory is root. 237 parent_dir = os.path.dirname(current_dir) 238 if (parent_dir == current_dir): 239 break 240 241 if ((self.root_cutoff is not None) and (self.root_cutoff == current_dir)): 242 break 243 244 current_dir = parent_dir 245 246 # If no file was found, use the base dir. 247 return os.path.join(base_dir, filename)
A source spec for loading from a project, which will look in the current directory and all parents until a matching file is found.
201 def __init__(self, 202 root_cutoff: typing.Union[str, None] = None, 203 filename: typing.Union[str, None] = None, 204 **kwargs: typing.Any) -> None: 205 super().__init__(**kwargs) 206 207 self.root_cutoff: typing.Union[str, None] = root_cutoff 208 """ If set, stop searching parents if this directory is encountered. """
A label set by each subclass to identify the type of source spec. Generally, a user-friendly version of the class name.
190 def get_help_lines(self) -> typing.List[str]: 191 return [ 192 'Project Config File', 193 'Load configurations from a "project" config file.', 194 'To find a project configuration file, we will look in the current directory and all parents (until root).', 195 'The first file found with the correct name will be loaded.', 196 'It is recommended to keep this file in your project\'s root directory.', 197 'This allows you to execute commands from anywhere in the project using the correct configuration settings.', 198 f"The file must be named: '{self.get_filename()}'.", 199 ]
Get lines of text describing how this source is loaded. This text is intended to be used in a help prompt.
210 def get_default_base_dir(self) -> typing.Union[str, None]: 211 return os.path.abspath(os.getcwd())
Retrieve the default base dir (usually from edq.config.settings) for use when no base dir is explicitly set.
213 def get_default_filename(self) -> typing.Union[str, None]: 214 return edq.config.common._config_filename
Retrieve the default filename (usually from edq.config.settings) for use when no filename is explicitly set.
216 def resolve_path(self, 217 override_path: typing.Union[str, None] = None, 218 ) -> str: 219 if (override_path is not None): 220 return override_path 221 222 base_dir = self.get_base_dir() 223 if (base_dir is None): 224 raise ValueError(f"Unable to resolve a config base dir for class {type(self)}.") 225 226 filename = self.get_filename() 227 if (filename is None): 228 raise ValueError(f"Unable to resolve a config filename for class {type(self)}.") 229 230 current_dir = base_dir 231 for _ in range(edq.util.dirent.DEPTH_LIMIT): 232 path = os.path.join(current_dir, filename) 233 if (os.path.isfile(path)): 234 return path 235 236 # Check if current directory is root. 237 parent_dir = os.path.dirname(current_dir) 238 if (parent_dir == current_dir): 239 break 240 241 if ((self.root_cutoff is not None) and (self.root_cutoff == current_dir)): 242 break 243 244 current_dir = parent_dir 245 246 # If no file was found, use the base dir. 247 return os.path.join(base_dir, filename)
Get the path that should be use to load config. This method is free to traverse the disk to find the desired path.