Skip to content

fix(dspy): keep fields when copying an Example with no visible fields - #10637

Open
Zhuoxi2000 wants to merge 1 commit into
stanfordnlp:mainfrom
Zhuoxi2000:fix-example-copy-falsy-base
Open

Zhuoxi2000 wants to merge 1 commit into
stanfordnlp:mainfrom
Zhuoxi2000:fix-example-copy-falsy-base

Conversation

@Zhuoxi2000

Copy link
Copy Markdown

📝 Changes Description

Example.__init__ checks if base and isinstance(base, ...). __len__ skips dspy_* keys, so an Example that holds only dspy_* metadata, or only an input split such as Example().with_inputs("question"), is falsy. In that case copy(), without() and Example(base=...) return a blank Example and give no warning:

dspy.Example().with_inputs("question").copy(question="q", answer="a")._input_keys  # None
dspy.Example(dspy_uuid="u1", dspy_split="train").copy().toDict()                   # {}

This follows up #9946, which made copies keep the input/label split but did not change the truthiness check. This PR drops base and from both branches. isinstance already excludes None, and an empty dict still gives an empty store.

Regression test: test_example_copy_preserves_fields_when_example_has_no_visible_fields in tests/primitives/test_example.py. It fails on current main (2151e3a) with assert None == {'question'} and passes with this change. tests/primitives, tests/predict, tests/teleprompt, tests/evaluate, tests/datasets and tests/adapters pass (1268 passed, 295 skipped), and ruff check (v0.15.0) is clean on the changed files.

✅ Contributor Checklist

  • Pre-Commit checks are passing (locally and remotely) (verified locally; CI pending)
  • Title of your PR / MR corresponds to the required format
  • Commit message follows required format {label}(dspy): {message}

⚠️ Warnings

None. Only falsy Example bases change behaviour. A falsy dict base gave an empty store before this change and still does.

AI assistance

I used Claude (Claude Code) to look for correctness gaps in dspy/primitives/example.py. It flagged the truthiness check and drafted the failing test and the two-line fix. I reproduced the failure on main, reviewed the change, and can explain it. Prompts, roughly:

  • "Look for cases where Example.copy() / without() / Example(base=...) lose fields or input keys."
  • "Write a failing regression test first, then the minimal fix."

Example.__init__ guarded the base branch with `if base and ...`. Since
__len__ skips dspy_* keys, an Example that only holds dspy_* metadata or
an input/label split (e.g. `Example().with_inputs("question")`) is falsy,
so copy(), without() and Example(base=...) silently dropped its store and
input keys. Check the type only, as the isinstance test already rules
out None.
@greptile-apps

greptile-apps Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

[Medium impact] The scoped Example constructor change is safe to merge: no actionable issues were found, and the executed checks confirm metadata retention, input-split preservation, and compatibility with existing constructor paths.

Summary

This PR fixes copies of an Example with no visible fields.

  • Copies keep fields from Examples that look empty.

No actionable issues were found in the Example constructor change. The new regression test passed, all 23 Example tests passed, and 35 focused checks passed for copying, removing fields, direct construction, independent input-key sets, and compatibility with None, empty dictionaries, and Prediction objects. The Example constructor change is safe to merge.

T-Rex validation blocked

The checks completed, but their scripts and output could not be uploaded because this environment exposes no artifact-upload facility. This does not change the observed test results.

Reviews (1) · Last reviewed commit: "fix(dspy): keep fields when copying an E..." · Reviewed by Greptile

This branch has not been deployed

No deployments
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.

1 participant