57 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Python
		
	
	
			
		
		
	
	
			57 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Python
		
	
	
"""Deal with YAML input."""
 | 
						|
 | 
						|
from __future__ import annotations
 | 
						|
 | 
						|
from typing import Any
 | 
						|
 | 
						|
from .objects import Input
 | 
						|
 | 
						|
 | 
						|
class UndefinedSubstitution(Exception):
 | 
						|
    """Error raised when we find a substitution that is not defined."""
 | 
						|
 | 
						|
    def __init__(self, input_name: str) -> None:
 | 
						|
        """Initialize the undefined substitution exception."""
 | 
						|
        super().__init__(f"No substitution found for input {input_name}")
 | 
						|
        self.input = input
 | 
						|
 | 
						|
 | 
						|
def extract_inputs(obj: Any) -> set[str]:
 | 
						|
    """Extract input from a structure."""
 | 
						|
    found: set[str] = set()
 | 
						|
    _extract_inputs(obj, found)
 | 
						|
    return found
 | 
						|
 | 
						|
 | 
						|
def _extract_inputs(obj: Any, found: set[str]) -> None:
 | 
						|
    """Extract input from a structure."""
 | 
						|
    if isinstance(obj, Input):
 | 
						|
        found.add(obj.name)
 | 
						|
        return
 | 
						|
 | 
						|
    if isinstance(obj, list):
 | 
						|
        for val in obj:
 | 
						|
            _extract_inputs(val, found)
 | 
						|
        return
 | 
						|
 | 
						|
    if isinstance(obj, dict):
 | 
						|
        for val in obj.values():
 | 
						|
            _extract_inputs(val, found)
 | 
						|
        return
 | 
						|
 | 
						|
 | 
						|
def substitute(obj: Any, substitutions: dict[str, Any]) -> Any:
 | 
						|
    """Substitute values."""
 | 
						|
    if isinstance(obj, Input):
 | 
						|
        if obj.name not in substitutions:
 | 
						|
            raise UndefinedSubstitution(obj.name)
 | 
						|
        return substitutions[obj.name]
 | 
						|
 | 
						|
    if isinstance(obj, list):
 | 
						|
        return [substitute(val, substitutions) for val in obj]
 | 
						|
 | 
						|
    if isinstance(obj, dict):
 | 
						|
        return {key: substitute(val, substitutions) for key, val in obj.items()}
 | 
						|
 | 
						|
    return obj
 |