Skip to content

Commit 2aa633f

Browse files
committed
Merge worktree-fix-python-drifts-2026-05-26 — Python FR5a envelope drifts (3 fixtures reconciled, ledgers empty)
2 parents db0b52f + 9f664a0 commit 2aa633f

4 files changed

Lines changed: 12 additions & 14 deletions

File tree

server/python/src/metaobjects/parser.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,11 @@ def _build(
159159
attr_name = key[len(ATTR_PREFIX):]
160160
# ADR-0007: @-prefixing a reserved structural body key is invalid.
161161
# Detected inline as each @-attr key is processed (matches TS parser-core).
162+
# FR5a: emit the envelope at the PARENT body level (do NOT push the
163+
# offending @-key onto the path) — matches TS parser-core which calls
164+
# errSource() without descending into the @-key. Pushing would emit
165+
# a deeper jsonPath than the reference port.
162166
if attr_name in _RESERVED_STRUCTURAL_KEYS:
163-
builder.push_key(key)
164167
result.errors.append(
165168
MetaError(
166169
f"node '{wrapper}' uses reserved structural key '{attr_name}' "
@@ -170,7 +173,6 @@ def _build(
170173
envelope=_current_envelope(source, builder),
171174
)
172175
)
173-
builder.pop()
174176
continue
175177
schema = registry.attr_schema(type_, sub_type, attr_name)
176178
node.set_attr(attr_name, value, sub_type=schema.value_type if schema else None)

server/python/src/metaobjects/super_resolve.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,15 @@ def _walk(
3535
effective_pkg = node.package or ctx_pkg or None
3636
target = _resolve(node.super_ref, effective_pkg, index)
3737
if target is None:
38+
# FR5a / ADR-0009: attach the referrer node's source envelope so the
39+
# error carries provenance (files[]/jsonPath). Without this, the
40+
# envelope defaults to an empty/code source — divergent from TS.
3841
errors.append(MetaError(
3942
f"the SuperClass '{node.super_ref}' does not exist "
4043
f"(referenced by {node.fqn()})",
4144
ErrorCode.ERR_UNRESOLVED_SUPER,
4245
path=node.fqn(),
46+
envelope=node.source,
4347
))
4448
else:
4549
node.super_data = target
Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
{
2-
"_comment": "FR5a envelope-shape gates: TS is the reference port for source.format / source.files / source.jsonPath. Python drifts on two fixtures (parser source-threading differences): error-extends-nonexistent (the Python super-resolve error path returns empty files[] + jsonPath '$'; TS captures the referrer node's full envelope), and error-reserved-word-as-attr (Python threads source one level deeper, to the offending @attr; TS stops at the parent field.object). Track until the Python loader's error-construction sites are reconciled to TS's source-emission sites.",
3-
"fixtures": [
4-
"error-extends-nonexistent",
5-
"error-reserved-word-as-attr"
6-
]
2+
"_comment": "FR5a envelope-shape gates: TS is the reference port for source.format / source.files / source.jsonPath. Ledger empty — Python's parser ERR_RESERVED_ATTR site and super-resolve ERR_UNRESOLVED_SUPER site now emit the same canonical jsonPath TS does (reconciled 2026-05-26).",
3+
"fixtures": []
74
}
Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
{
22
"language": "python",
3-
"_comment": "FR5a envelope-shape gate: Python's emitted source field differs from TS (the FR5a reference port) for these YAML fixtures. The code-set check still runs; only the full-envelope assertion is skipped. Each entry MUST be accompanied by the drift summary below. Reconcile per the FR5a follow-up — make Python's error-construction sites emit the same canonical jsonPath TS does.",
4-
"fixtures": [
5-
"error-yaml-reserved-as-attr"
6-
],
7-
"_drifts": {
8-
"error-yaml-reserved-as-attr": "Python threads source one level deeper, to the offending @attr; TS stops at the parent object.entity."
9-
}
3+
"_comment": "FR5a envelope-shape gate: ledger empty — Python's parser ERR_RESERVED_ATTR site (shared with the JSON path; the YAML desugar lowers to canonical JSON before the parser walks it) now emits the same canonical jsonPath TS does (reconciled 2026-05-26).",
4+
"fixtures": []
105
}

0 commit comments

Comments
 (0)