Skip to content

feat(core): SpEL-lite — @Value('#{...}') + @conditional_on_expression (v26.06.30)#55

Merged
ancongui merged 1 commit into
mainfrom
feat/spel-lite
Jun 7, 2026
Merged

feat(core): SpEL-lite — @Value('#{...}') + @conditional_on_expression (v26.06.30)#55
ancongui merged 1 commit into
mainfrom
feat/spel-lite

Conversation

@ancongui
Copy link
Copy Markdown
Contributor

@ancongui ancongui commented Jun 7, 2026

Summary

Wave 4 — a safe subset of Spring's SpEL for the #{ ... } form.

  • @Value("#{ ... }") evaluates arithmetic, comparison, boolean (and/or/not), ternary, lists/tuples, literals, ${key:default} placeholder substitution (numeric values participate in arithmetic), and an env mapping. Example: Value("#{${pyfly.workers} * 2}").
  • @conditional_on_expression("#{ ... }") (pyfly.context) registers a bean when the expression is truthy — Spring's @ConditionalOnExpression, evaluated in the config pass.
  • Safe by construction: parsed with ast, evaluated against a whitelist of node types — no attribute access, no function/method calls, no imports; eval is never used. evaluate / ExpressionError / is_expression are public in pyfly.core.expression.

Plain ${key} placeholders and literal @Value strings are unchanged.

Tests

tests/core/test_expression.py (7): arithmetic/boolean/ternary, placeholder substitution + numeric defaults, env, safety (rejects __import__, attribute access, unknown names), @Value SpEL, @conditional_on_expression via ConditionEvaluator.

Gates

mypy --strict (613) ✓ · ruff + ruff format ✓ · full suite 3777 passed, 1 skipped.

Bumps v26.06.29 → v26.06.30. Wave 4 remaining: Testcontainers. Then Wave 5 (docs + skills/agents).

… + bump v26.06.30

Wave 4 — a SAFE subset of Spring SpEL for the #{...} form (ast-parsed, whitelisted node
types, never eval()): arithmetic, comparison, boolean, ternary, lists, literals,
${key:default} placeholder substitution (numeric values participate in arithmetic), env mapping.
- @value('#{...}') evaluates expressions (plain ${} + literals unchanged).
- @conditional_on_expression('#{...}') registers a bean when truthy (Spring
  @ConditionalOnExpression), evaluated in the config pass.
- pyfly.core.expression.evaluate / ExpressionError / is_expression public.

Tests: tests/core/test_expression.py (7, incl. safety: rejects calls/attribute/unknown-name).
Gates: mypy --strict (613), ruff + format, full suite 3777 passed.
@ancongui ancongui merged commit fa1d8e0 into main Jun 7, 2026
5 checks passed
@ancongui ancongui deleted the feat/spel-lite branch June 7, 2026 09:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant