Synthesize typed NamedTuple._replace so extra fields are errors - #11642
Synthesize typed NamedTuple._replace so extra fields are errors#11642Henry Su (hsusul) wants to merge 1 commit into
Conversation
…ors. typeshed exposes _replace as **kwargs: Any, so unknown field names and incompatible values were accepted even though CPython raises TypeError.
|
🔒 Automated review in progress — Rich Chiodo (@rchiodo) is auto-reviewing this PR. |
| if (addGenericGetAttribute) { | ||
| FunctionType.addDefaultParams(replaceType); | ||
| } else { | ||
| constructorType.shared.parameters.forEach((param) => { |
There was a problem hiding this comment.
Warning · Non-blocking recommendation
Filtering parameters by the names self and cls removes legal NamedTuple fields with those names. For example, NamedTuple("NT", [("self", int)]) will not accept _replace(self=2). Skip only the actual receiver parameter and add regression coverage for both field names.
| replaceType, | ||
| FunctionParam.create( | ||
| param.category, | ||
| param._type, |
There was a problem hiding this comment.
Warning · Non-blocking recommendation
This derives replacement fields from the synthesized constructor while the class-syntax NamedTuple path builds the corresponding signature in dataClasses.ts. The duplicated policy can drift between class and factory NamedTuples; extract a shared field-signature builder or otherwise centralize this logic.
Rich Chiodo (rchiodo)
left a comment
There was a problem hiding this comment.
Approved via Review Center.
Heejae Chang (heejaechang)
left a comment
There was a problem hiding this comment.
Approved via Review Center.
Summary
._replace()is typed in typeshed as**kwargs: Any, so extra field names and incompatible values were accepted.TypeError: Got unexpected field names(and type mismatches fail similarly).__replace__was already synthesized with a keyword-only field signature on 3.13+;_replacenow uses the same signature for class-syntax and factory NamedTuples.__replace__behavior is unchanged.Test plan
npx jest typeEvaluator4.test.ts -t DataClassReplace1 --forceExit(frompackages/pyright-internal)npx jest typeEvaluator8.test.ts -t NamedTuple --forceExitnpx jest checker.test.ts -t Private1 --forceExitNT(1)._replace(y=2)reports an unknown-parameter error in the language server