Skip to content

dict_kwargs restricted to classes with an unresolved **kwargs - #981

Merged
mauvilsa merged 2 commits into
mainfrom
signature-kwargs-open
Sep 18, 2026
Merged

mauvilsa merged 2 commits into
mainfrom
signature-kwargs-open

Conversation

@mauvilsa

Copy link
Copy Markdown
Owner

What does this PR do?

dict_kwargs in a subclass spec exists for the keyword arguments that the parameter resolvers can't determine. Resolved parameters are meant to be given through init_args. Until now dict_kwargs accepted any key for any class, so a key that the class doesn't accept was either silently ignored or only showed up as a TypeError at instantiation. Now such a key fails during parsing, unless the class has a **kwargs that the resolvers could not resolve.

Keys that are resolved parameters are still accepted in dict_kwargs and get moved to init_args. This keeps backward compatibility, and it means configs keep working when an improvement to the resolvers turns a previously unresolved parameter into a resolved one.

The parameter resolvers now track whether a **kwargs was left unresolved. They represent it with a VAR_KEYWORD parameter named **, which can't collide with a real name. Cases that count as unresolved: **kwargs not used in the body, forwarded to something that has its own unresolved **kwargs, used in an unsupported way (unsupported assign, super call or call target, given as a keyword parameter), and the assumptions and stubs resolver fallbacks. Unpack[TypedDict] counts as resolved.

This is a behavior change: configs that put a key the class doesn't accept in dict_kwargs used to parse, and now fail. The changelog entry is under Changed for v5.0.0, and the "Unresolved parameters" section of the documentation describes the new behavior.

Before submitting

  • Did you read the contributing guideline?
  • If you used a coding agent, did you fully understand and validate all generated code and ensure it follows the contributing guidelines?
  • Did you update the documentation? (readme and public docstrings)
  • Did you write unit tests such that there is 100% coverage on related code? (required for bug fixes and new features)
  • Did you verify that new and existing tests pass locally?
  • [n/a] If this is a bug fix, did you verify that the tests fail without the code fix?
  • Did you make sure that all changes preserve backward compatibility?
  • Did you update the CHANGELOG including a pull request link? (not for typos, docs, test updates, or minor internal changes/refactors)

@mauvilsa mauvilsa added enhancement New feature or request refactor Improvements to the quality of the code labels Sep 18, 2026
@codecov

codecov Bot commented Sep 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (5e494f1) to head (a2340f4).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff            @@
##              main      #981   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           27        27           
  Lines         9078      9114   +36     
=========================================
+ Hits          9078      9114   +36     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@greptile-apps

greptile-apps Bot commented Sep 18, 2026

Copy link
Copy Markdown

RetriggerConfidence Score: 4/5

The implementation appears safe to merge after correcting the non-blocking changelog wording.

Findings

  1. P2 Malformed changelog sentence

Summary

This PR tracks unresolved **kwargs through parameter resolution and uses that information to restrict subclass dict_kwargs during parsing, help generation, and JSON Schema completion.

  • Records whether each generated class parser accepts arbitrary keyword names.
  • Moves resolved dict_kwargs parameters into init_args while rejecting unknown keys for closed signatures.
  • Preserves permissive behavior for genuinely unresolved forwarding and supported model extras.
  • Expands resolver, subclass, Pydantic, stub, and completion-schema coverage.
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Resolve class signature] --> B{Unresolved **kwargs?}
  B -->|Yes| C[Record accepted kwargs as True]
  B -->|No| D[Record resolved names and aliases]
  C --> E[Parse subclass specification]
  D --> E
  E --> F[Move resolved dict_kwargs keys to init_args]
  F --> G{Unexpected keys remain?}
  G -->|No| H[Parse init_args and retain valid unresolved kwargs]
  G -->|Yes, arbitrary kwargs accepted| H
  G -->|Yes, closed signature| I[Raise parsing error]
Loading

Reviews (1) · Last reviewed commit: "dict_kwargs restricted to classes with a..."

Comment thread CHANGELOG.rst Outdated
@sonarqubecloud

Copy link
Copy Markdown

@mauvilsa
mauvilsa merged commit 2d109be into main Sep 18, 2026
32 checks passed
@mauvilsa
mauvilsa deleted the signature-kwargs-open branch September 18, 2026 07:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request refactor Improvements to the quality of the code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant