@@ -273,8 +273,12 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> {
273
273
fields : & SmallMap < Name , bool > ,
274
274
) -> ClassSynthesizedField {
275
275
let metadata = FuncMetadata :: def ( self . module ( ) . name ( ) , cls. name ( ) . clone ( ) , UPDATE_METHOD ) ;
276
-
277
276
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
+ } ;
278
282
279
283
// ---- Overload: def update(m: Partial[C], /)
280
284
let full_typed_dict = self . as_typed_dict_unchecked ( cls) ;
@@ -296,16 +300,15 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> {
296
300
} ) ;
297
301
298
302
// ---- 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
300
305
. names_to_fields ( cls, fields)
301
306
. 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 ) )
308
308
. collect ( ) ;
309
+ if let Some ( extra) = & extra {
310
+ tuple_types. push ( get_tuple ( None , extra. clone ( ) ) ) ;
311
+ }
309
312
310
313
let iterable_ty = self . stdlib . iterable ( self . unions ( tuple_types) ) . to_type ( ) ;
311
314
@@ -321,13 +324,16 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> {
321
324
} ) ;
322
325
323
326
// ---- Overload: update(*, x=..., y=...)
324
- let keyword_params : Vec < _ > = self
327
+ let mut keyword_params = self
325
328
. names_to_fields ( cls, fields)
326
329
. filter ( |( _, field) | !field. is_read_only ( ) ) // filter read-only fields
327
330
. map ( |( name, field) | {
328
331
Param :: KwOnly ( name. clone ( ) , field. ty . clone ( ) , Required :: Optional ( None ) )
329
332
} )
330
- . collect ( ) ;
333
+ . collect :: < Vec < _ > > ( ) ;
334
+ if let Some ( extra) = extra {
335
+ keyword_params. push ( Param :: Kwargs ( None , extra) ) ;
336
+ }
331
337
332
338
let overload_kwargs = OverloadType :: Function ( Function {
333
339
signature : Callable :: list (
@@ -463,14 +469,18 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> {
463
469
} ) )
464
470
}
465
471
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
+
466
480
fn key_param ( & self , name : Option < & Name > ) -> Param {
467
481
Param :: PosOnly (
468
482
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) ,
474
484
Required :: Required ,
475
485
)
476
486
}
0 commit comments