stubgen: emit reduced field()/Field() in class stubs (with optional doc metadata)#3223
stubgen: emit reduced field()/Field() in class stubs (with optional doc metadata)#3223tobyh-canva wants to merge 1 commit intofacebook:mainfrom
field()/Field() in class stubs (with optional doc metadata)#3223Conversation
…oc metadata) - Re-emit dataclass field() / Pydantic Field() with type-relevant kwargs; strip metadata/validation - Simplify default_factory to simple refs or lambda: ... placeholder - include_docstrings keeps Field description/title; solver fallback for = ... Made-with: Cursor
|
Hi @tobyh-canva! Thank you for your pull request and welcome to our community. Action RequiredIn order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you. ProcessIn order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA. Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks! |
field()/Field() in class stubs (with optional doc metadata)
|
I'm not 100% sure if this is the best approach, I considered emitting any field with a default as I guess an alternative approach would be for stubgen to emit an explicit Please let me know what approach you would prefer :) |
|
Hey @tobyh-canva thanks for starting contributions to our repo, a necessary check before importing this into our repo is to sign the CLA - https://code.facebook.com/cla |
|
Also a quick heads-up, this diff is also trying to achieve the same goal - #3225 Maybe this could be a collab between you both, I would suggest to reach out to them on discord to prevent any redundant commits / conflicts |
|
Thanks @NathanTempest, I'll try and get myself added to Canva's corporate CLA tomorrow |
Context
As identified in #3221, stub generation for class body annotated assignments only handled simple RHS values (e.g. literals,
...).dataclasses.field/ PydanticFieldcalls are not "simple" text, so stubs either dropped the real__init__/ field behavior or were forced into lossy workarounds. Callers that care aboutkw_only, defaults, and field metadata need something closer to the real declaration without copying the whole module.Intent
Make
.pyioutput forfield(...)andField(...)type-checking oriented: keep a reduced call that still reflects init-altering options, strip runtime-only or validation noise, and avoid echoing heavydefault_factorybodies. Optional Pydantic schema doc strings onFieldshould follow the sameinclude_docstringsswitch as other stub doc content.Changes
extract.rs)AnnAssignRHS, after simple literals, try a structured strip offield/Field(by callee name, includingdataclasses.field/pydantic.Field-style attributes).Field): defaults,default_factory,init,kw_only(dataclass), aliasing-related kwargs (Pydantic), etc.; drop the rest (e.g.metadata,min_length, …).default_factory: keep only simple callable refs (bare name ora.bchains); otherwise emitdefault_factory=lambda: ....include_docstrings, PydanticFieldalso keepsdescriptionandtitle.field/Field(e.g.*args), use the solver plusClassField::dataclass_flags_ofto emit= ...when the solved field’s init parameter has a default, matching the existing init-default notion (with the documented Pydantic caveat for dual name/alias params).ClassField:dataclass_flags_ofispub(crate)for stubgen.stubgen/mod.rs): dataclass + Pydantic coverage for stripping,default_factory, complex factory placeholder, mixed fields, and docstring retention under config.Testing
cargo test -p pyrefly stubgen::tests::Fixes #3221.