Skip to content

Commit bce6ca8

Browse files
Adopt 0098 carries-key rename in the harness (#260)
* Adopt 0098 carries-key rename in the harness Proposal 0098 renamed the structured_output_invalid carries keys to the llm-provider §7 error field names (output_content / error_message). Teach the harness carries reader to resolve those §7 names to the Python StructuredOutputInvalid attributes (raw_content / failure_description), and un-defer the two fixtures it unblocks (022 / 023). Resolution is direct-first: an attribute named exactly as the carries key wins, and the alias is only a fallback, so it cannot misdirect a different error that legitimately exposes those field names. Harness-only; no src or user-facing change. 0098 stays textual-only. * Use sentinel getattr in carries resolver Address a review comment on PR #260: the direct-first lookup used hasattr + getattr (two accesses). Switch to a sentinel getattr default so the direct case is a single lookup. Behavior unchanged; these exception attributes are plain, so there was no observable double-fire.
1 parent 7eba913 commit bce6ca8

3 files changed

Lines changed: 25 additions & 14 deletions

File tree

conformance.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -960,7 +960,7 @@ note = "ScoredDocument.document stays echoed text (string | null) but the echo r
960960
[proposals."0098"]
961961
status = "textual-only"
962962
since = "0.17.0"
963-
note = "A conformance-adapter directive rename with no shipped-module component: the three structured_output_invalid carries keys that did not track their §7 fields are renamed (raw_response_content -> output_content, failure_description_present -> error_message_present, failure_description_mentions -> error_message_mentions), and §5.12 states the key-naming convention normatively (a key MUST name a §7 error field, bare field = exact-equality with subset match for a mapping-valued field, _present / _mentions the closed flavor set). No openarmature-python shipped module changes; the conformance harness adopts the renamed keys (llm-provider fixtures 022 / 023) in the v0.17.0 fixture-wiring PR."
963+
note = "A conformance-adapter directive rename with no shipped-module component: the three structured_output_invalid carries keys that did not track their §7 fields are renamed (raw_response_content -> output_content, failure_description_present -> error_message_present, failure_description_mentions -> error_message_mentions), and §5.12 states the key-naming convention normatively (a key MUST name a §7 error field, bare field = exact-equality with subset match for a mapping-valued field, _present / _mentions the closed flavor set). No openarmature-python shipped module changes; the conformance harness bridges the renamed §7 keys (output_content / error_message) to the impl error attributes (raw_content / failure_description) via its carries alias map, so llm-provider fixtures 022 / 023 run."
964964

965965
# Spec v0.94.0 (proposal 0099). Cohere /v2/embed input_type widened;
966966
# the extras-vs-managed-field claims pinned (retrieval-provider §8.4).

tests/conformance/harness/wire.py

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,27 @@ def _as_carries_mapping(value: Any) -> Mapping[str, Any] | None:
217217

218218

219219
def _get_carries_attr(exc: BaseException, name: str) -> Any:
220-
# Allow fixture-naming-friendly aliases for the carries block. The
221-
# spec fixtures use ``raw_response_content`` (the wire-side label);
222-
# the Python exception class names its attribute ``raw_content``.
223-
aliases = {"raw_response_content": "raw_content"}
224-
canonical = aliases.get(name, name)
225-
return getattr(exc, canonical, None)
220+
# Resolve a carries key to an exception attribute. Proposal 0098 renamed the
221+
# structured_output_invalid carries keys to the llm-provider §7 error field
222+
# names (output_content / error_message), but the Python
223+
# StructuredOutputInvalid names those attributes raw_content /
224+
# failure_description, so the alias below bridges the §7 names to the impl
225+
# attributes. (The pre-0098 wire-side label raw_response_content is fully
226+
# retired from the fixtures.)
227+
#
228+
# Resolve DIRECT-FIRST: an attribute named exactly as the carries key wins,
229+
# and the alias is a fallback only when that attribute is absent. This keeps
230+
# the alias from misdirecting a different error that legitimately exposes an
231+
# output_content / error_message attribute, and stays correct if the impl
232+
# ever renames its attributes to the §7 names.
233+
aliases = {
234+
"output_content": "raw_content",
235+
"error_message": "failure_description",
236+
}
237+
# Single lookup for the direct case: a sentinel default avoids the
238+
# hasattr + getattr double access (which would fire a descriptor twice).
239+
missing = object()
240+
direct = getattr(exc, name, missing)
241+
if direct is not missing:
242+
return direct
243+
return getattr(exc, aliases.get(name, name), None)

tests/conformance/test_llm_provider.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -122,13 +122,6 @@
122122
# the conformance fixture wiring rides the v0.17.0 fixture-wiring PR,
123123
# except the provider/streaming rows, which stay deferred for their
124124
# existing reasons (Anthropic 0037 / Gemini 0038 / streaming 0062).
125-
# Proposal 0098 (spec v0.93.0) structured-output carries-key rename.
126-
"022-structured-output-parse-failure": (
127-
"Proposal 0098 carries-key rename; wire.py carries adoption rides the v0.17.0 fixture-wiring PR"
128-
),
129-
"023-structured-output-validation-failure": (
130-
"Proposal 0098 carries-key rename; wire.py carries adoption rides the v0.17.0 fixture-wiring PR"
131-
),
132125
# Proposal 0095 (spec v0.91.0) adaptive call-level retry + reask.
133126
"061-call-level-retry-per-attempt-override": (
134127
"Proposal 0095 call.retry / wire_requests harness wiring; rides the v0.17.0 fixture-wiring PR"

0 commit comments

Comments
 (0)