@@ -51,8 +51,10 @@ use crate::types::types::TParam;
5151use crate :: types:: types:: TParams ;
5252use crate :: types:: types:: Type ;
5353
54+ const CLEAR_METHOD : Name = Name :: new_static ( "clear" ) ;
5455const GET_METHOD : Name = Name :: new_static ( "get" ) ;
5556const POP_METHOD : Name = Name :: new_static ( "pop" ) ;
57+ const POPITEM_METHOD : Name = Name :: new_static ( "popitem" ) ;
5658const SETDEFAULT_METHOD : Name = Name :: new_static ( "setdefault" ) ;
5759const KEY_PARAM : Name = Name :: new_static ( "key" ) ;
5860const DEFAULT_PARAM : Name = Name :: new_static ( "default" ) ;
@@ -681,6 +683,61 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> {
681683 } ) ) )
682684 }
683685
686+ fn all_items_are_removable ( & self , cls : & Class , fields : & SmallMap < Name , bool > ) -> bool {
687+ !self
688+ . typed_dict_extra_items ( cls)
689+ . extra_item ( self . stdlib )
690+ . read_only
691+ && self
692+ . names_to_fields ( cls, fields)
693+ . all ( |( _, field) | !field. is_read_only ( ) && !field. required )
694+ }
695+
696+ fn get_typed_dict_clear (
697+ & self ,
698+ cls : & Class ,
699+ fields : & SmallMap < Name , bool > ,
700+ ) -> Option < ClassSynthesizedField > {
701+ if !self . all_items_are_removable ( cls, fields) {
702+ return None ;
703+ }
704+ Some ( ClassSynthesizedField :: new ( Type :: Function ( Box :: new (
705+ Function {
706+ signature : Callable :: list (
707+ ParamList :: new ( vec ! [ self . class_self_param( cls, true ) ] ) ,
708+ Type :: None ,
709+ ) ,
710+ metadata : FuncMetadata :: def ( self . module ( ) . name ( ) , cls. name ( ) . clone ( ) , CLEAR_METHOD ) ,
711+ } ,
712+ ) ) ) )
713+ }
714+
715+ fn get_typed_dict_popitem (
716+ & self ,
717+ cls : & Class ,
718+ fields : & SmallMap < Name , bool > ,
719+ ) -> Option < ClassSynthesizedField > {
720+ if !self . all_items_are_removable ( cls, fields) {
721+ return None ;
722+ }
723+ Some ( ClassSynthesizedField :: new ( Type :: Function ( Box :: new (
724+ Function {
725+ signature : Callable :: list (
726+ ParamList :: new ( vec ! [ self . class_self_param( cls, true ) ] ) ,
727+ Type :: Tuple ( Tuple :: Concrete ( vec ! [
728+ self . stdlib. str ( ) . clone( ) . to_type( ) ,
729+ self . get_typed_dict_value_type_from_fields( cls, fields) ,
730+ ] ) ) ,
731+ ) ,
732+ metadata : FuncMetadata :: def (
733+ self . module ( ) . name ( ) ,
734+ cls. name ( ) . clone ( ) ,
735+ POPITEM_METHOD ,
736+ ) ,
737+ } ,
738+ ) ) ) )
739+ }
740+
684741 pub fn get_typed_dict_synthesized_fields ( & self , cls : & Class ) -> Option < ClassSynthesizedFields > {
685742 let metadata = self . get_metadata_for_class ( cls) ;
686743 let td = metadata. typed_dict_metadata ( ) ?;
@@ -691,9 +748,15 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> {
691748 UPDATE_METHOD => self . get_typed_dict_update( cls, & td. fields) ,
692749 VALUES_METHOD => self . get_typed_dict_values( cls, & td. fields) ,
693750 } ;
751+ if let Some ( m) = self . get_typed_dict_clear ( cls, & td. fields ) {
752+ fields. insert ( CLEAR_METHOD , m) ;
753+ }
694754 if let Some ( m) = self . get_typed_dict_pop ( cls, & td. fields ) {
695755 fields. insert ( POP_METHOD , m) ;
696756 }
757+ if let Some ( m) = self . get_typed_dict_popitem ( cls, & td. fields ) {
758+ fields. insert ( POPITEM_METHOD , m) ;
759+ }
697760 if let Some ( m) = self . get_typed_dict_setdefault ( cls, & td. fields ) {
698761 fields. insert ( SETDEFAULT_METHOD , m) ;
699762 }
0 commit comments