@@ -273,8 +273,12 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> {
273273 fields : & SmallMap < Name , bool > ,
274274 ) -> ClassSynthesizedField {
275275 let metadata = FuncMetadata :: def ( self . module ( ) . name ( ) , cls. name ( ) . clone ( ) , UPDATE_METHOD ) ;
276-
277276 let self_param = self . class_self_param ( cls, true ) ;
277+ let extra = if let ExtraItems :: Extra ( extra) = self . typed_dict_extra_items ( cls) {
278+ Some ( extra. ty )
279+ } else {
280+ None
281+ } ;
278282
279283 // ---- Overload: def update(m: Partial[C], /)
280284 let full_typed_dict = self . as_typed_dict_unchecked ( cls) ;
@@ -296,16 +300,15 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> {
296300 } ) ;
297301
298302 // ---- Overload: update(m: Iterable[tuple[Literal["key"], value]], /)
299- let tuple_types: Vec < Type > = self
303+ let get_tuple = |name, ty| Type :: Tuple ( Tuple :: Concrete ( vec ! [ self . name_or_str( name) , ty] ) ) ;
304+ let mut tuple_types: Vec < Type > = self
300305 . names_to_fields ( cls, fields)
301306 . filter ( |( _, field) | !field. is_read_only ( ) ) // filter read-only fields
302- . map ( |( name, field) | {
303- Type :: Tuple ( Tuple :: Concrete ( vec ! [
304- name_to_literal_type( name) ,
305- field. ty. clone( ) ,
306- ] ) )
307- } )
307+ . map ( |( name, field) | get_tuple ( Some ( name) , field. ty ) )
308308 . collect ( ) ;
309+ if let Some ( extra) = & extra {
310+ tuple_types. push ( get_tuple ( None , extra. clone ( ) ) ) ;
311+ }
309312
310313 let iterable_ty = self . stdlib . iterable ( self . unions ( tuple_types) ) . to_type ( ) ;
311314
@@ -321,13 +324,16 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> {
321324 } ) ;
322325
323326 // ---- Overload: update(*, x=..., y=...)
324- let keyword_params : Vec < _ > = self
327+ let mut keyword_params = self
325328 . names_to_fields ( cls, fields)
326329 . filter ( |( _, field) | !field. is_read_only ( ) ) // filter read-only fields
327330 . map ( |( name, field) | {
328331 Param :: KwOnly ( name. clone ( ) , field. ty . clone ( ) , Required :: Optional ( None ) )
329332 } )
330- . collect ( ) ;
333+ . collect :: < Vec < _ > > ( ) ;
334+ if let Some ( extra) = extra {
335+ keyword_params. push ( Param :: Kwargs ( None , extra) ) ;
336+ }
331337
332338 let overload_kwargs = OverloadType :: Function ( Function {
333339 signature : Callable :: list (
@@ -463,14 +469,18 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> {
463469 } ) )
464470 }
465471
472+ fn name_or_str ( & self , name : Option < & Name > ) -> Type {
473+ if let Some ( name) = name {
474+ name_to_literal_type ( name)
475+ } else {
476+ self . stdlib . str ( ) . clone ( ) . to_type ( )
477+ }
478+ }
479+
466480 fn key_param ( & self , name : Option < & Name > ) -> Param {
467481 Param :: PosOnly (
468482 Some ( KEY_PARAM . clone ( ) ) ,
469- if let Some ( name) = name {
470- name_to_literal_type ( name)
471- } else {
472- self . stdlib . str ( ) . clone ( ) . to_type ( )
473- } ,
483+ self . name_or_str ( name) ,
474484 Required :: Required ,
475485 )
476486 }
0 commit comments