Skip to content

Train: #725 (0186 ph1), #735 (0330 item 0, 0376), #736 (0362) on master 2fc3fac - #738

Merged
rmorozov merged 16 commits into
masterfrom
claude/project-thread-53pwid
Nov 2, 2026
Merged

rmorozov merged 16 commits into
masterfrom
claude/project-thread-53pwid

Conversation

@rmorozov

@rmorozov rmorozov commented Nov 2, 2026

Copy link
Copy Markdown
Member

Integration train: stacks three final PRs on master 2fc3fac with no conflicts, so CI and the perf verdict run once on the merged head.

Merging this marks the three PRs merged. Task statuses are synced in an index PR afterwards (0376 and 0362 done; 0186 and 0330 stay open). Codex: security review never ran on #736.


Generated by Claude Code

claude added 16 commits November 1, 2026 16:42
…86 phase 1)

CMake option JINJA2CPP_TEST_ORACLE=bundled|python|venv (cmake/parity_oracle.cmake) adds a
CTest fixture that runs generate.py --out <build>/parity-oracle --any-version under another
Python Jinja2 at test time, and jinja2cpp_parity_oracle, which runs the narrow suite with
JINJA2CPP_TEST_ORACLE_DIR naming that directory. Where the two oracles agree a case is judged
by the allow-list as before; where they differ it is reported as tracks-bundled,
tracks-oracle, neither or not-run in report.md, and fails only under
JINJA2CPP_TEST_ORACLE_STRICT=1. Bundled builds are unchanged. Files 0372 for the corpus gap
on code points changed after Unicode 15.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AWNL7oJQzYFjjoGQPuDCF2
generate.py --out no longer sweeps other *.json files from the directory and refuses
expected/; report cells and strict-mode messages replace invalid UTF-8 and cut on a character
boundary; a malformed oracle.json or index.json is a failure of OracleCorpusMatches rather than
an exception at tear-down; clearer message for a venv without jinja2; README notes that ';'
separates requirements.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AWNL7oJQzYFjjoGQPuDCF2
…, odd/even, urlencode and call blocks (0362)

- IHostObject gains GetSlice (x[a:b:c], omitted bounds are None) and Reversed
  (reversed(x)); without them the engine raises Python's TypeError.
- A slice of a value without items raises as Jinja2's compiled obj[slice] does
  (TypeError, KeyError for a dict, UndefinedError for an undefined value); a slice of
  literals still folds to undefined through getitem. The parser asks each slice
  whether it folds, memoised so a chain of slices is walked once.
- last on a host object is next(reversed(x)); reverse tries Reversed before
  iterating.
- odd/even take value % 2: a string formats 2, anything else that is no number
  raises (undefined under every policy).
- urlencode iterates a host object that has __iter__ and unpacks every item as
  `k, v` with Python's ValueError/TypeError messages (a two-character string is a
  pair).
- A call block resolves an engine object's call operator (joiner()), which refuses
  caller= as Python does, and writes a string result unescaped; any other result is
  Python's TypeError of joining the output (removes the 0156 divergence line).
- Files 0377 (lazy filter results are no sequences) and 0378 (host operators).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AWNL7p4Lh5EPebNn13VNn4
The venv stamp records the base interpreter, so a new JINJA2CPP_TEST_ORACLE_PYTHON rebuilds the
venv; OracleCorpusMatches compares every rendering input (context, env, templates), not only the
template, so a directory generated before a case changed fails instead of reporting deltas.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AWNL7oJQzYFjjoGQPuDCF2
…d trip (0330 item 0, 0376)

- InternalValue::CopyFrom is the copy assignment forced inline; Slot::Bind
  calls it for an lvalue, so RenderLoopInSlots no longer calls an out-of-line
  .isra clone. operator= stays a plain inline call: forcing it inline grew
  BindArg/FillDefaultArgs out of ParseCallParams (for_range +0.10%).
- SameStringGetter returns optional<basic_string> built in place, and
  GetAsSameString returns it directly: one copy, no move through the PLT and
  no second copy out of expected's error slot.
- tojson writes a char string value through AsStringView before falling back
  to GetAsSameString, so no string is copied to be escaped.
- StrArg moves its result out of the optional.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AWNL7pVkQgmq9G2qPBVG5H
…ssignment)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AWNL7pVkQgmq9G2qPBVG5H
…lice bounds and urlencode of undefined (0362)

- A slice of literals folds to an undefined that names the object and the slice, so
  StrictUndefined refuses it, DebugUndefined prints it and a slice of it fails, as in
  Jinja2 (`5[1:][1:]`).
- An undefined slice bound is Python's "slice indices must be integers" TypeError.
- urlencode iterates an undefined value as nothing (StrictUndefined refuses).
- reverse of a host object keeps the object alive behind its items (WithParent).
- Files 0379 (`loop|urlencode` iterates the rest of the loop), pinned by
  filters.urlencode_loop.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AWNL7p4Lh5EPebNn13VNn4
…e (deliberate, 0362)

Ruslan's decision: follow Jinja2 for non-string results (TypeError), but keep a plain
string escaped where Jinja2 writes it raw, so a callable's data stays escaped.
Recorded in the task file and release-2.0.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AWNL7p4Lh5EPebNn13VNn4
@rmorozov
rmorozov marked this pull request as ready for review November 2, 2026 13:16
@rmorozov
rmorozov merged commit 808cbdb into master Nov 2, 2026
52 checks passed
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.

2 participants