From 6d6f4a509fdb6144fdcafbe53b5e5eaf2124dd5a Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Wed, 4 Feb 2026 12:58:13 +0000 Subject: [PATCH] fix: resolve CI linting and type errors --- src/promptforge/core/template.py | 100 ++++++++++++++++++++++++++++++- 1 file changed, 99 insertions(+), 1 deletion(-) diff --git a/src/promptforge/core/template.py b/src/promptforge/core/template.py index 7ab44fe..eedac74 100644 --- a/src/promptforge/core/template.py +++ b/src/promptforge/core/template.py @@ -1,3 +1,5 @@ +"""Jinja2-based template engine for prompt rendering.""" + from typing import Any, Dict, List, Optional from jinja2 import Environment, BaseLoader, TemplateSyntaxError, StrictUndefined, UndefinedError from jinja2.exceptions import TemplateError @@ -7,6 +9,8 @@ from .exceptions import MissingVariableError, InvalidPromptError class TemplateEngine: + """Jinja2 template engine for prompt rendering with variable substitution.""" + def __init__(self): self.env = Environment( loader=BaseLoader(), @@ -17,6 +21,14 @@ class TemplateEngine: ) def get_variables(self, content: str) -> List[str]: + """Extract variable names from template content. + + Args: + content: Template content with {{variable}} syntax. + + Returns: + List of variable names found. + """ from jinja2 import meta ast = self.env.parse(content) return sorted(meta.find_undeclared_variables(ast)) @@ -27,6 +39,20 @@ class TemplateEngine: variables: Optional[Dict[str, Any]] = None, required_variables: Optional[List[PromptVariable]] = None, ) -> str: + """Render template with variable substitution. + + Args: + content: Template content. + variables: Dictionary of variable values. + required_variables: List of variable definitions for validation. + + Returns: + Rendered content. + + Raises: + MissingVariableError: If a required variable is missing. + InvalidPromptError: If template has syntax errors. + """ variables = variables.copy() if variables else {} required_variables = required_variables or [] @@ -56,4 +82,76 @@ class TemplateEngine: except TemplateSyntaxError as e: raise InvalidPromptError(f"Template syntax error: {e.message}") except (UndefinedError, TemplateError) as e: - raise InvalidPromptError(f"Template rendering error: {e}") \ No newline at end of file + raise InvalidPromptError(f"Template rendering error: {e}") + + def validate_variables( + self, + variables: Dict[str, Any], + required_variables: List[PromptVariable], + ) -> List[str]: + """Validate variable values against definitions. + + Args: + variables: Provided variable values. + required_variables: Variable definitions. + + Returns: + List of validation error messages (empty if valid). + """ + errors = [] + + for var in required_variables: + if var.name not in variables: + if var.required and var.default is None: + errors.append(f"Missing required variable: {var.name}") + continue + + value = variables[var.name] + var_type = var.type.value + + if var_type == "string": + if not isinstance(value, str): + errors.append(f"{var.name}: must be a string") + elif var_type == "integer": + try: + int(value) + except (ValueError, TypeError): + errors.append(f"{var.name}: must be an integer") + elif var_type == "float": + try: + float(value) + except (ValueError, TypeError): + errors.append(f"{var.name}: must be a number") + elif var_type == "boolean": + if isinstance(value, str): + if value.lower() not in ("true", "false", "0", "1"): + errors.append(f"{var.name}: must be a boolean") + elif var_type == "choice": + if var.choices and value not in var.choices: + errors.append( + f"{var.name}: must be one of {', '.join(var.choices)}" + ) + + return errors + + def render_prompt( + self, + prompt_content: str, + variables: Dict[str, Any], + variable_definitions: List[PromptVariable], + ) -> str: + """Render a complete prompt with validation. + + Args: + prompt_content: Raw prompt template content. + variables: Variable values. + variable_definitions: Variable definitions from prompt. + + Returns: + Rendered prompt string. + """ + errors = self.validate_variables(variables, variable_definitions) + if errors: + raise MissingVariableError(f"Variable validation failed: {', '.join(errors)}") + + return self.render(prompt_content, variables, variable_definitions)