MCPcopy
hub / github.com/github/spec-kit / evaluate_expression

Function evaluate_expression

src/specify_cli/workflows/expressions.py:434–480  ·  view source on GitHub ↗

Evaluate a template string with ``{{ ... }}`` expressions. If the entire string is a single expression, returns the raw value (preserving type). Otherwise, substitutes each expression inline and returns a string. Parameters ---------- template: The template string

(template: str, context: Any)

Source from the content-addressed store, hash-verified

432
433
434def evaluate_expression(template: str, context: Any) -> Any:
435 """Evaluate a template string with ``{{ ... }}`` expressions.
436
437 If the entire string is a single expression, returns the raw value
438 (preserving type). Otherwise, substitutes each expression inline
439 and returns a string.
440
441 Parameters
442 ----------
443 template:
444 The template string (e.g., ``"{{ steps.plan.output.task_count }}"``
445 or ``"Processed {{ inputs.spec }}"``.
446 context:
447 A ``StepContext`` or compatible object.
448
449 Returns
450 -------
451 The resolved value (any type for single-expression templates,
452 string for multi-expression or mixed templates).
453 """
454 if not isinstance(template, str):
455 return template
456
457 namespace = _build_namespace(context)
458
459 # Single expression: return typed value (preserving type).
460 #
461 # The fast path must fire only when the whole template is one ``{{ ... }}``
462 # block. Neither ``fullmatch`` nor a match-span check on ``_EXPR_PATTERN``
463 # can decide this reliably: the non-greedy body stops at the first ``}}``,
464 # so ``fullmatch`` over-expands ``"{{ a }} {{ b }}"`` to garbage (returning
465 # ``None`` and bypassing interpolation, issue #3208), while a span check
466 # trips over a literal ``}}`` inside a string argument such as
467 # ``{{ inputs.text | contains('}}') }}`` and mis-routes it to interpolation
468 # (coercing its typed return to ``str``). ``_is_single_expression`` scans
469 # for a block-closing ``}}`` outside string literals, so both cases resolve
470 # correctly.
471 stripped = template.strip()
472 if _is_single_expression(stripped):
473 return _evaluate_simple_expression(stripped[2:-2].strip(), namespace)
474
475 # Multi-expression: string interpolation
476 def _replacer(m: re.Match[str]) -> str:
477 val = _evaluate_simple_expression(m.group(1).strip(), namespace)
478 return str(val) if val is not None else ""
479
480 return _EXPR_PATTERN.sub(_replacer, template)
481
482
483def evaluate_condition(condition: str, context: Any) -> bool:

Callers 15

executeMethod · 0.90
_resolveMethod · 0.90
executeMethod · 0.90
executeMethod · 0.90
executeMethod · 0.90
executeMethod · 0.90
executeMethod · 0.90
executeMethod · 0.90
test_simple_variableMethod · 0.90

Calls 3

_build_namespaceFunction · 0.85
_is_single_expressionFunction · 0.85