docs(market-data): the envelope builder states its own reason for returning None, not a claim about what parse accepts - #651
Conversation
…urning None, not a claim about what parse accepts `to_price_feed_envelope`'s docstring justified its `None` by asserting "there is no such thing as an envelope with no prices, and `parse` rightly refuses one". #647 (closing #642) makes an envelope carrying only `fx` valid and accepted, so that borrowed justification is about to be false — a host that can read one public FX rate but not every close can now hand back a rate-only repair for the #612 refusal. The rule itself is unchanged and correct; only the reason given for it was wrong. This lane dates itself from its own rows (`as_of` is `max(row date)`), so with no rows there is no observed session to declare one from — a reason that holds whether or not #647 lands, which is why it is stated that way rather than restating the post-#647 contract on a branch where it is not yet true. Stated as one condition rather than a list of causes, because the claim being replaced went stale by enumerating and a first draft of this one repeated the mistake: it said `None` meant "priced nothing, or the split rule dropped everything", which a bundle whose only priced symbol is a benchmark falsifies — that yields no envelope while having priced something the split rule never touched. Also corrects the same borrowed justification in the mirroring test docstring. Behavior is unchanged — the diff is provably docstring-only (ASTs are identical to origin/main once docstrings are stripped). Flagged while in here and filed as #648: a currency rate the bundle did resolve is discarded along with the envelope, because `fx` is assembled below the early return. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
86e74c7 to
98d26f0
Compare
|
Self-review before merge caught a real defect in the first draft of this docstring, fixed in 98d26f0. The replacement paragraph originally glossed the The bundle did price something, and the split rule never fired — benchmarks are simply outside this envelope's scope by default. So both stated causes were false while the return value was still That is the same failure mode as the claim this PR exists to remove: an enumeration that was true when written and silently stopped being exhaustive. Rewritten as a single condition — nothing priced was both in scope and reconcilable onto one split basis — which covers all three ways Also re-verified the paragraph's other load-bearing claim, that a dropped instrument is recorded as a gap before the early return, so the coverage fact outlives the Re-checked after the fix: 49/49 suites, and both files still AST-identical to |
to_price_feed_envelopejustified itsNonereturn by borrowing a rule from a different module:#647 (closing #642) makes an envelope carrying only
fxvalid and accepted, so that borrowed justification is about to be false. The rule it justifies is fine; only the reason was wrong.What this does
States this lane's own reason instead, which is invariant: the envelope is defined over instrument closes and dates itself from them —
as_ofismax(row date), read off the rows themselves — so with no rows there is no observed session to declare one from.Deliberately not written as "
parsenow accepts fx-only envelopes". #647 is still open, so onmainthat statement would be false today, and permanently false if #647 never lands. Phrasing it as this lane's own rule reads correctly either way, and explicitly disclaims being a restatement of whatparseaccepts, which is what stops the same drift recurring.Two smaller corrections in the same docstring:
Nonedoes not mean only "the bundle priced nothing" — the split-basis rule above can drop everything the bundle did price.None(dropped instruments are recorded as gaps on the bundle before the early return), so the return value does not conceal anything.Mirrored surface:
tests/test_market_data.py'stest_i_a_bundle_that_priced_nothing_yields_no_envelopecarried the same borrowed justification in its own docstring. Corrected there too. The assertions are untouched.Behavior is unchanged, and that is checked rather than asserted
The diff is provably docstring-only: both files' ASTs are identical to
HEADonce docstrings are stripped, and differ only when they are kept.python3 tests/run_all.py→ 49/49 suites passtests/test_market_data.pystandalone → 51/51, and the edited test was confirmed to actually execute rather than skip (this suite has no skips at all — worth stating explicitly, since a suite that skips itself and still prints green is a failure mode this repo has hit)Relationship to #647
No conflict: #647 does not touch
market_data.py. This can land before or after it in either order, which is the point of the invariant phrasing.Filed, not fixed: #648
Noticed while in here.
fxis assembled below theif not rows: return Noneguard, so a bundle that priced nothing but did resolve a currency rate discards the rate.Bundle.usablenames that exact state as worth caching, so a bundle can be usable solely on the strength of a rate this function then throws away. Reproduced against the recorded fake provider.Harmless on
maintoday (nothing accepts a lone rate); #647 is what makes it bite, since that rate is precisely the rate-only repair #642 built the lane for. Not fixed here because it needs a contract decision — what date a rate declares when no close is present to date it from — rather than moving a block. Details and repro in #648.Closes nothing; #648 tracks the follow-up.