Skip to content

Try targeted candidates in explain phase before random sampling#4718

Open
Zac-HD wants to merge 4 commits intoHypothesisWorks:masterfrom
Zac-HD:claude/fix-issue-4715-uonex
Open

Try targeted candidates in explain phase before random sampling#4718
Zac-HD wants to merge 4 commits intoHypothesisWorks:masterfrom
Zac-HD:claude/fix-issue-4715-uonex

Conversation

@Zac-HD
Copy link
Copy Markdown
Member

@Zac-HD Zac-HD commented Apr 25, 2026

When the explain phase tries to determine whether an arg slice can vary freely without affecting failure, it currently relies on pure random sampling. For tests like assert n1 == n2 that misses the only passing value (the other arg's current value), so we'd report a misleading # or any other generated value comment.

Before falling back to random sampling, we now try a few deterministic candidates: the minimal value, the smallest non-minimal value, and the values borrowed from each other arg slice with matching length and types. This catches the equality-comparison case, while leaving the existing behaviour for genuinely free arg slices.

Fixes #4715.

@Zac-HD Zac-HD enabled auto-merge April 25, 2026 20:24
Comment on lines +652 to +657
continue
try:
value = choice_from_index(idx, node.type, node.constraints)
except (NotImplementedError, AssertionError, IndexError):
break
if not choice_permitted(value, node.constraints):
Copy link
Copy Markdown
Member

@Liam-DeVoe Liam-DeVoe Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of try/excepting, we should break if compute_max_children(node.type, node.constraints) < idx. As evidenced by these excepts, choice_from_index is not designed to handle semantically-invalid indexes nicely.

(independently, I'm surprised claude has decided that NotImplementedError can be thrown here)

claude added 4 commits April 27, 2026 20:31
When the explain phase tries to determine whether an arg slice can vary
freely without affecting failure, it currently relies on pure random
sampling. For tests like ``assert n1 == n2`` that misses the only
passing value (the other arg's current value), so we'd report a
misleading ``# or any other generated value`` comment.

Before falling back to random sampling, we now try a few deterministic
candidates: the minimal value, the smallest non-minimal value, and the
values borrowed from each other arg slice with matching length and
types. This catches the equality-comparison case, while leaving the
existing behaviour for genuinely free arg slices.
The previous implementation included defensive paths (try/except around
choice_from_index, choice_permitted guards, was_forced handling inside the
borrow loop) that weren't reachable from the test suite, breaking the
100% line/branch coverage gate.

Drop the idx=0 / idx=1 candidates -- random sampling already covers those,
and the borrow-from-sibling path is what actually catches assert n1 == n2.
The engine's existing handling of invalid attempts in the surrounding loop
makes the choice_permitted guard redundant.
The CI check-format job runs shed against every file the branch touches and
asserts no diff. Other formatters (e.g. ruff) reformat differently from shed,
so running ./build.sh format before pushing is the only reliable way to keep
the check green.
@Zac-HD Zac-HD force-pushed the claude/fix-issue-4715-uonex branch from ccfdcb9 to c31c869 Compare April 27, 2026 21:06
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.

Explain mode gives misleading comment when comparing two integers

3 participants