Skip to content

Warn instead of printing on ambiguous output rules - #103

Draft
cemde wants to merge 1 commit into
liukidar:mainfrom
cemde:fix/79-warn-not-print
Draft

Warn instead of printing on ambiguous output rules#103
cemde wants to merge 1 commit into
liukidar:mainfrom
cemde:fix/79-warn-not-print

Conversation

@cemde

@cemde cemde commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator

Bug

Vode.get reported an ambiguous ruleset with print. The source carried a # TODO: use warnings.

Impact

A bare print cannot be filtered, captured by pytest.warns, routed to a log, or promoted to an error with -W error, so CI cannot fail on it and a notebook user scrolls past it. Meanwhile the effect it reports, silently discarding every matched rule but the first, is permanent.

Fix

warnings.warn(
    f"Multiple output rules matched for key '{key}' in status '{self.status}', "
    "only the first is applied.",
    stacklevel=2,
)

UserWarning, the default, because an ambiguous ruleset is a defect in what the user wrote at authoring time rather than a dubious runtime condition inside the library. It is also the category shown by default in __main__ and notebooks. The guarding test asserts pytest.warns(UserWarning, ...), and RuntimeWarning does not subclass it.

One neighbouring test deliberately builds an ambiguous ruleset to assert the first-rule policy, so it now carries a local filterwarnings marker. Verified that it hides nothing: the file passes under -W error::UserWarning, and the gate's warning summary still contains only the pre-existing equinox deprecation.

Known limitation: stacklevel

stacklevel=2 attributes the warning to the caller of Vode.get, which is right for a direct vode.get("e"). It is wrong for vode(u, output="e"), because Vode.__call__ calls self.get(...) internally, so the report lands on _vode.py:230. That is the form every tutorial uses.

There is no single correct value: direct get wants 2, the __call__ path wants 3. Left at 2 pending a decision on which entry point to optimise for. Worth knowing that under the default warning filter, dedup is per location, so in the __call__ case every ambiguous Vode in a model collapses to one report.

Under jit the warning fires at trace time only. The print it replaces had the same limitation.

Closes #79

@cemde
cemde marked this pull request as draft August 9, 2026 14:49
Vode.get printed "WARNING: Multiple output rules matched..." to stdout. A bare print cannot be filtered, captured, routed to a log or promoted with -W error, and inside a jitted step it fires once at trace time and never again, while the rule it silently discards stays discarded.

Closes liukidar#79
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ambiguous output rules print to stdout instead of warning

1 participant