refactor(subscriber): make OutboxSubscriberConfig validate itself#111
Merged
Conversation
Move subscriber-knob validation from factory._validate_subscriber_config into OutboxSubscriberConfig.__post_init__ (guarded super-call + _validate) so every construction path is guarded, not just the factory's. Behavior preserved exactly (EMPTY->None ack_policy mapping). Replace skip_file_prefixes with a manual stacklevel walk (_subscriber_warn) since the 3.13 C warn won't skip the dataclass __init__ '<string>' frame now between __post_init__ and the user. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…hange Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
lesnik512
added a commit
that referenced
this pull request
Jun 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Subscriber-knob validation lived in
subscriber/factory.py::_validate_subscriber_config, called fromcreate_subscriber.OutboxSubscriberConfigwas a bare@dataclasswith no__post_init__, so constructing it directly bypassed every guard. This moves validation intoOutboxSubscriberConfig.__post_init__so every construction path —@broker.subscriber,@router.subscriber, direct construction — is validated; there's no way in that skips it. The factory shrinks to construction/wiring.Candidate #3 from the 2026-06-23 architecture review. Change record:
planning/changes/2026-06-23.03-self-validating-subscriber-config/change.md.What changed
OutboxSubscriberConfig.__post_init__→ guardedsuper().__post_init__()(upstreamSubscriberUsecaseConfighas none today, but dataclasses call only the most-derived one — the guard keeps a future upstream init running) thenself._validate()._validate()holds the relocated checks. Behavior preserved exactly: maps_ack_policy is EMPTY → Noneso checks match on the explicitly-passed policy as before (the NACK+NoRetry advisory still fires only on an explicitNACK_ON_ERROR, not on the default that resolves to it).factory.pydrops_validate_subscriber_configand its call.Version-robustness wrinkle (the interesting part)
Moving validation under the dataclass-generated
__init__inserts a frame whoseco_filenameis the literal"<string>"between the user's call and__post_init__. The 3.13 Cwarnings.warn(skip_file_prefixes=...)does not skip that frame (3.14 does), so warnings mis-attributed to<string>and the FastAPI-router attribution test failed under docker/3.13.Replaced
skip_file_prefixeswith_subscriber_warn, which computesstacklevelby walking out to the first non-internal frame (this package / faststream /<string>) — robust across CPython versions and across the direct vs router paths (which differ in frame count).Verification
test_unit.pyreject/warn/no-warning cases (via@broker.subscriber),test_fastapi.pyrouter-path attribution,test_fake.pydirect-construction.just test: 543 passed, 100% coverage (docker / Python 3.13).just lint-ci: clean.🤖 Generated with Claude Code