Skip to content

fix(predict): materialize default_factory for input fields - #10792

Open
BlueX888 wants to merge 1 commit into
stanfordnlp:mainfrom
BlueX888:contrib/input-default-factory
Open

BlueX888 wants to merge 1 commit into
stanfordnlp:mainfrom
BlueX888:contrib/input-default-factory

Conversation

@BlueX888

@BlueX888 BlueX888 commented Nov 3, 2026 •

Copy link
Copy Markdown

📝 Changes Description

Predict populated missing input defaults only when FieldInfo.default was not PydanticUndefined. For an input declared with default_factory, .default is undefined, so the factory was never called: the field was absent from the prompt, and the module logged Not all input fields were provided ... Missing: ['context'] even though the field had a default. The output-field path already materializes factories through get_default(call_default_factory=True).

class Sig(dspy.Signature):
    context: list[str] = dspy.InputField(default_factory=lambda: ["DEFAULT_CONTEXT"])
    question: str = dspy.InputField()
    answer: str = dspy.OutputField()

dspy.configure(lm=spy_lm)
Predict(Sig)(question="test")  # prompt omits context; warning fires

This change populates missing inputs with FieldInfo.is_required() and materializes factory fields via get_default(call_default_factory=True), passing the raw input values supplied so far as validated_data for factories that accept an input dict (DSPy does not validate inputs, so this mirrors the available values rather than pydantic model validation). Literal defaults keep their existing value and identity; required-field warnings, optional-annotation behavior, and output defaults are unchanged. The unused PydanticUndefined import is removed.

A related PR (#10034) made an equivalent Predict change in a stacked feature branch (isaac/rlm-namespace-collisions); it is not in current main, which still has the old code (verified against c8176a8).

✅ Contributor Checklist

  • Pre-Commit checks are passing (locally: pytest tests/predict 614 passed, ruff check clean, ty check with the same 16 pre-existing diagnostics as base)
  • Title of your PR / MR corresponds to the required format (fix(predict): ...)
  • Commit message follows the required format (fix(predict): ...)

⚠️ Warnings

Tests use the existing spy_lm helper and the default adapter; the fix is covered through Predict._forward_preprocess, which is shared by forward and async paths.

@greptile-apps

greptile-apps Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Low impact] The PR appears safe to merge; both previous findings are fixed and no new actionable issues remain.

Summary

Predict now fills missing inputs declared with default_factory.

  • Predict fills missing optional inputs from their default factories.

Reviews (2) · Last reviewed commit: "fix(predict): materialize default_factor..." · Reviewed by Greptile

Comment thread dspy/predict/predict.py Resolved
Comment thread tests/predict/test_predict.py Resolved
Populate missing inputs with FieldInfo.is_required() and materialize factory
fields via get_default(call_default_factory=True). Literal defaults keep
their existing value and identity. Pass the values supplied so far as
validated_data so factories that accept an input dict work, and enable
logger propagation in the warning regression test. Factory-backed inputs
were previously never populated, so the adapter omitted them from the prompt
and the missing-input warning fired even though the field had a default.
@BlueX888
BlueX888 force-pushed the contrib/input-default-factory branch from 29f51cf to 6bcc0c6 Compare November 3, 2026 08:34
@BlueX888

BlueX888 commented Nov 3, 2026 •

Copy link
Copy Markdown
Author

Addressed both findings in 6bcc0c6:

  • Factories that accept validated data now receive the raw input values supplied so far via get_default(call_default_factory=True, validated_data=available), with a regression test for default_factory=lambda data: [data["question"]]. Zero-argument factories still work; pydantic's floor (>=2.11.0) supports validated_data. DSPy does not validate inputs, so validated_data mirrors available values rather than pydantic model-validation semantics.
  • The warning test calls log_test_helper() for consistency with the neighboring warning tests. On closer inspection pytest's caplog attaches its handler directly to non-propagating loggers, so the assertion was already non-vacuous when run alone; the call is defensive, not a bug fix.

Verified: pytest tests/predict 614 passed / 148 skipped, ruff check clean, ty check has the same 16 pre-existing diagnostics as base.

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