feat: v0.5.0rc1 polish — py.typed, @deprecated, OTel adapter (Proposal 3)#19
Merged
Conversation
…Config Two-thirds of Proposal 3 polish from the plan: - flow_doctor/py.typed (zero-byte PEP 561 marker) ships in the wheel via [tool.setuptools.package-data] so mypy/pyright treat flow-doctor's annotations as authoritative when consumers depend on flow-doctor in --strict mode. Verified the marker lands in the built wheel. - typing_extensions>=4.5 added to runtime deps (PEP 702 backport for Python 3.9-3.12; stdlib in 3.13+). - @deprecated on flow_doctor.init() emits a runtime DeprecationWarning pointing at FlowDoctor.builder() (default category) so 0.4.0 consumers actually see the migration prompt on startup. Removed in 0.6.0. - @deprecated on NotifyChannelConfig uses category=None — static-only, no runtime warning. The omnibus form is still the internal lingua franca that the builder folds typed configs into via to_channel_config(), so a runtime warning here would fire on every typed config that gets lifted to legacy. The static __deprecated__ attribute still surfaces the migration hint in mypy/pyright when consumers construct it explicitly. - Suite filterwarnings entry suppresses init()'s runtime warning inside our own tests; downstream consumers still see it at their call site. 5 new tests cover: runtime DeprecationWarning emission from init(), silent runtime + present __deprecated__ on NotifyChannelConfig, and a regression that the recommended migration path (FlowDoctor.builder() + typed notifier configs) is deprecation-clean even though it folds typed configs through to_channel_config() internally. Suite: 340/340 pass (335 prior + 5 new). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Final piece of Proposal 3 polish. Pure-Python, no opentelemetry-* dep — the actual OTLP exporter is deferred to v0.6.0 per the plan's open question #5 so the optional dep family lands in its own release cycle. What ships here is the SHAPE that exporter will emit, so consumers running on Datadog / Honeycomb / Grafana Cloud / Sentry-via-OTel can convert reports themselves today via their own collector. flow_doctor/otel.py implements report_to_otel_span_event(report) per the plan's mapping table: - flow_name → resource.service.name - context.stage → event.name (falls back to "report") - error_type → attributes["exception.type"] - error_message → attributes["exception.message"] - traceback → attributes["exception.stacktrace"] - severity → severity_text + severity_number (critical=FATAL/21, error=ERROR/17, warning=WARN/13) - created_at → time_unix_nano (handles naive-UTC datetimes safely) - error_signature → attributes["flow_doctor.error_signature"] - cascade_source → attributes["flow_doctor.cascade_source"] - dedup_count > 1 → attributes["flow_doctor.dedup_count"] - logs → attributes["flow_doctor.logs"] - context (rest) → flattened into attributes with "context." prefix (nested dicts dot-flatten; non-primitives coerced to str so attribute values stay OTel-safe) Duplicates are pruned: flow_name doesn't reappear as context.flow_name on attributes (already on the resource), and stage doesn't reappear as context.stage (already promoted to event.name). 16 new tests cover: top-level shape, resource mapping, event.name promotion + fallback, severity text+number for error/warning/critical, time_unix_nano correctness for both tz-aware and naive timestamps, exception field placement, flow_doctor.* prefixed attributes, nested- dict flattening, dedup_count gating, homogeneous-list preservation vs mixed-list stringification, and duplicate-promotion pruning. Suite: 356/356 pass (340 prior + 16 new). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Version bump 0.4.0 → 0.5.0 in flow_doctor/__init__.py + pyproject.toml. CHANGELOG.md gains a v0.5.0 section folding in this release's three proposals (Pydantic v2 config + builder, FlowDoctorProtocol + testing plugin + async + contextvars, py.typed + @deprecated + OTel adapter) plus the dedup-signature normalization that had been queued under "Unreleased". 0.6.0 roadmap explicitly captures the deferred work: OTLP exporter, pydantic-settings BaseSettings, hard removal of the deprecated APIs. PyPI publish stays a manual step. Suite: 356/356 pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bump 0.5.0 → 0.5.0rc1 in __init__.py + pyproject.toml so the planned plug-and-play release ships as a release candidate first. PEP 440 pre-release tag means pip skips it by default — consumers must pass `--pre` to opt in, which keeps the soak builds off anyone pinning flow-doctor>=0.4 in production until 0.5.0 final lands. CHANGELOG: rename the section header to 0.5.0rc1 with a one-paragraph note about the soak intent. The full bullet list is the planned 0.5.0 content verbatim — 0.5.0 final will republish it once the rcN cycle clears. Suite: 356/356 pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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
Closes Proposal 3 from
private/plug-and-play-260513.mdand cuts the v0.5.0 release. Three small, independent pieces of polish on top of PR #18.What's in
flow_doctor/py.typed— zero-byte PEP 561 marker shipping in the wheel via[tool.setuptools.package-data]. Verified the file lands in the built wheel. Consumers using mypy/pyright in--strictmode now treat flow-doctor's annotations as authoritative.@deprecatedonflow_doctor.init()(runtimeDeprecationWarningpointing atFlowDoctor.builder()) andNotifyChannelConfig(static-only viacategory=Nonesince it's still the internal lingua franca the builder folds typed configs into). Addstyping_extensions>=4.5to runtime deps (PEP 702 backport for Python 3.9–3.12; stdlib in 3.13+). Suite-levelfilterwarningskeeps our own legacy-path tests clean; downstream consumers still see the warning at their call site.flow_doctor.otel.report_to_otel_span_event(report)— pure-Python OTel SpanEvent serialization. Mapsflow_name → resource.service.name,context["stage"] → event.name, exception fields → OTel exception attributes, severity → severity_text + severity_number, created_at → time_unix_nano, context dict flattened with"context."prefix and primitives coerced. Noopentelemetry-*dep — the OTLP exporter notifier itself stays deferred to v0.6.0 per the plan's open question Fix README badges — static shields #5.__version__+pyproject.tomlversion bumped 0.4.0 → 0.5.0. CHANGELOG.md gains a v0.5.0 section folding in Proposals 1+2+3 plus the dedup-signature normalization that had been queued under "Unreleased". 0.6.0 roadmap captures the deferred work (OTLP exporter,pydantic-settingsBaseSettings, hard removal of deprecated APIs).Not in this PR (manual / follow-up)
Test plan
pytest tests/→ 356/356 pass (340 prior + 5 deprecation + 16 OTel = 21 new).flow_doctor/py.typed(verified viapython -m zipfile -l).FlowDoctor.builder()path is deprecation-clean (no runtime warnings);flow_doctor.init()emits the expectedDeprecationWarning.🤖 Generated with Claude Code