Optimized comments

This commit is contained in:
Kevin Veen-Birkenbach 2025-01-10 02:23:31 +01:00
parent 166055422e
commit 35815ce5aa

View File

@ -1,54 +1,87 @@
class ConfigurationResolver: class ConfigurationResolver:
def __init__(self, config): def __init__(self, config):
"""
Initializes the ConfigurationResolver with a configuration dictionary.
Args:
config (dict): The configuration to resolve links in.
"""
self.config = config self.config = config
def resolve_links(self): def resolve_links(self):
""" """
Resolves all `link` entries in the configuration. Resolves all `link` entries in the configuration by replacing them with
the referenced configuration entry.
""" """
self._recursive_resolve(self.config, self.config) self._recursive_resolve(self.config, self.config)
def _recursive_resolve(self, current_config, root_config, path=""): def _recursive_resolve(self, current_config, root_config, path=""):
""" """
Recursively resolves `link` entries in the configuration. Recursively traverses the configuration to resolve all `link` entries.
Args:
current_config (dict or list): The current section of the configuration being processed.
root_config (dict): The root of the configuration to resolve links against.
path (str): The current path in the configuration for debugging purposes.
""" """
if isinstance(current_config, dict): if isinstance(current_config, dict):
# Traverse all key-value pairs in the dictionary
for key, value in list(current_config.items()): for key, value in list(current_config.items()):
if key == "link": if key == "link":
# Found a `link` entry, attempt to resolve it
try: try:
print(f"Resolving link '{value}' at path '{path}'") # Debugging print(f"Resolving link '{value}' at path '{path}'") # Debugging
target = self._find_entry(root_config, value.lower().replace(" ", "_")) target = self._find_entry(root_config, value.lower().replace(" ", "_"))
if isinstance(target, dict): if isinstance(target, dict):
# Replace the current dictionary with the resolved dictionary
current_config.clear() current_config.clear()
current_config.update(target) current_config.update(target)
elif isinstance(target, str): elif isinstance(target, str):
# Replace the `link` entry with the resolved string
current_config[key] = target current_config[key] = target
else: else:
raise ValueError(f"Expected a dictionary or string for link '{value}', got {type(target)}")
except KeyError as e:
raise ValueError( raise ValueError(
f"Key error while resolving link '{value}': {str(e)}. Current path: {key}, Current config: {current_config}" f"Expected a dictionary or string for link '{value}', got {type(target)}"
)
except KeyError as e:
# Handle unresolved links
raise ValueError(
f"Key error while resolving link '{value}': {str(e)}. "
f"Current path: {path}, Current config: {current_config}"
) )
else: else:
# Recursively resolve non-`link` entries
self._recursive_resolve(value, root_config, path=f"{path}.{key}") self._recursive_resolve(value, root_config, path=f"{path}.{key}")
elif isinstance(current_config, list): elif isinstance(current_config, list):
# Traverse all items in the list
for index, item in enumerate(current_config): for index, item in enumerate(current_config):
self._recursive_resolve(item, root_config, path=f"{path}[{index}]") self._recursive_resolve(item, root_config, path=f"{path}[{index}]")
def _find_entry(self, config, path): def _find_entry(self, config, path):
""" """
Finds an entry in the configuration by a dot-separated path. Finds an entry in the configuration by navigating a dot-separated path.
Supports both dictionaries and lists, but does not navigate into `subitems`
unless explicitly required by the path. Args:
config (dict or list): The configuration to search within.
path (str): The dot-separated path to the desired entry.
Returns:
dict or str: The resolved entry.
Raises:
KeyError: If the path cannot be resolved.
ValueError: If the resolved entry is not of the expected type.
""" """
parts = path.split('.') parts = path.split('.') # Split the path into segments
current = config current = config
for part in parts: for part in parts:
part = part.replace(" ", "_") # Normalize the part name part = part.replace(" ", "_") # Normalize part name
if isinstance(current, list): if isinstance(current, list):
# Look for a matching entry in the list # Search for a matching entry in a list
found = next( found = next(
( (
item item
@ -65,7 +98,7 @@ class ConfigurationResolver:
current = found current = found
elif isinstance(current, dict): elif isinstance(current, dict):
# Look for a key match in the dictionary # Search for a key match in a dictionary
key = next((k for k in current if k.lower().replace(" ", "_") == part), None) key = next((k for k in current if k.lower().replace(" ", "_") == part), None)
if key is None: if key is None:
raise KeyError( raise KeyError(
@ -75,27 +108,30 @@ class ConfigurationResolver:
current = current[key] current = current[key]
else: else:
# Invalid path segment
raise ValueError( raise ValueError(
f"Invalid path segment '{part}'. Current type: {type(current)}. " f"Invalid path segment '{part}'. Current type: {type(current)}. "
f"Path so far: {' > '.join(parts[:parts.index(part)+1])}" f"Path so far: {' > '.join(parts[:parts.index(part)+1])}"
) )
# Stop navigating into `subitems` if the path doesn't explicitly require it # Stop navigating into `subitems` unless explicitly required by the path
if isinstance(current, dict) and "subitems" in current and isinstance(current["subitems"], list): if isinstance(current, dict) and "subitems" in current and isinstance(current["subitems"], list):
if part == "subitems": if part != "subitems":
current = current["subitems"] break # Stop navigation if `subitems` is not explicitly in the path
else:
break # Do not navigate further unless explicitly in the path
# Ensure the resolved target is a dictionary or string # Ensure the resolved target is a dictionary or string
if not isinstance(current, (dict, str)): if not isinstance(current, (dict, str)):
raise ValueError(f"Expected a dictionary or string for path '{path}', got {type(current)}. Current value: {current}") raise ValueError(
f"Expected a dictionary or string for path '{path}', got {type(current)}. Current value: {current}"
)
return current return current
def get_config(self): def get_config(self):
""" """
Returns the resolved configuration. Returns the fully resolved configuration.
Returns:
dict: The resolved configuration.
""" """
return self.config return self.config