@@ -4177,6 +4177,121 @@ class AllTheThings(TypedDict):
41774177        self .assertEqual (AllTheThings .__optional_keys__ , frozenset ({'c' , 'd' }))
41784178        self .assertEqual (AllTheThings .__readonly_keys__ , frozenset ({'a' , 'b' , 'c' }))
41794179        self .assertEqual (AllTheThings .__mutable_keys__ , frozenset ({'d' }))
4180+     
4181+     def  test_extra_keys_non_readonly (self ):
4182+         class  Base (TypedDict , closed = True ):
4183+             __extra_items__ : str 
4184+         
4185+         class  Child (Base ):
4186+             a : NotRequired [int ]
4187+         
4188+         self .assertEqual (Child .__required_keys__ , frozenset ({}))
4189+         self .assertEqual (Child .__optional_keys__ , frozenset ({'a' }))
4190+         self .assertEqual (Child .__readonly_keys__ , frozenset ({}))
4191+         self .assertEqual (Child .__mutable_keys__ , frozenset ({'a' }))
4192+ 
4193+     def  test_extra_keys_readonly (self ):
4194+         class  Base (TypedDict , closed = True ):
4195+             __extra_items__ : ReadOnly [str ]
4196+         
4197+         class  Child (Base ):
4198+             a : NotRequired [str ]
4199+         
4200+         self .assertEqual (Child .__required_keys__ , frozenset ({}))
4201+         self .assertEqual (Child .__optional_keys__ , frozenset ({'a' }))
4202+         self .assertEqual (Child .__readonly_keys__ , frozenset ({}))
4203+         self .assertEqual (Child .__mutable_keys__ , frozenset ({'a' }))
4204+     
4205+     def  test_extra_key_required (self ):
4206+         with  self .assertRaisesRegex (
4207+             TypeError ,
4208+             "Special key __extra_items__ does not support Required and NotRequired" 
4209+         ):
4210+             TypedDict ("A" , {"__extra_items__" : Required [int ]}, closed = True )
4211+ 
4212+         with  self .assertRaisesRegex (
4213+             TypeError ,
4214+             "Special key __extra_items__ does not support Required and NotRequired" 
4215+         ):
4216+             TypedDict ("A" , {"__extra_items__" : NotRequired [int ]}, closed = True )
4217+     
4218+     def  test_regular_extra_items (self ):
4219+         class  ExtraReadOnly (TypedDict ):
4220+             __extra_items__ : ReadOnly [str ]
4221+ 
4222+         class  ExtraRequired (TypedDict ):
4223+             __extra_items__ : Required [str ]
4224+ 
4225+         class  ExtraNotRequired (TypedDict ):
4226+             __extra_items__ : NotRequired [str ]
4227+         
4228+         self .assertEqual (ExtraReadOnly .__required_keys__ , frozenset ({'__extra_items__' }))
4229+         self .assertEqual (ExtraReadOnly .__optional_keys__ , frozenset ({}))
4230+         self .assertEqual (ExtraReadOnly .__readonly_keys__ , frozenset ({'__extra_items__' }))
4231+         self .assertEqual (ExtraReadOnly .__mutable_keys__ , frozenset ({}))
4232+ 
4233+         self .assertEqual (ExtraRequired .__required_keys__ , frozenset ({'__extra_items__' }))
4234+         self .assertEqual (ExtraRequired .__optional_keys__ , frozenset ({}))
4235+         self .assertEqual (ExtraRequired .__readonly_keys__ , frozenset ({}))
4236+         self .assertEqual (ExtraRequired .__mutable_keys__ , frozenset ({'__extra_items__' }))
4237+ 
4238+         self .assertEqual (ExtraNotRequired .__required_keys__ , frozenset ({}))
4239+         self .assertEqual (ExtraNotRequired .__optional_keys__ , frozenset ({'__extra_items__' }))
4240+         self .assertEqual (ExtraNotRequired .__readonly_keys__ , frozenset ({}))
4241+         self .assertEqual (ExtraNotRequired .__mutable_keys__ , frozenset ({'__extra_items__' }))
4242+     
4243+     def  test_closed_inheritance (self ):
4244+         class  Base (TypedDict , closed = True ):
4245+             __extra_items__ : ReadOnly [Union [str , None ]]
4246+         
4247+         class  Child (Base ):
4248+             a : int 
4249+             __extra_items__ : int 
4250+ 
4251+         class  GrandChild (Child , closed = True ):
4252+             __extra_items__ : str 
4253+ 
4254+         self .assertEqual (Base .__required_keys__ , frozenset ({}))
4255+         self .assertEqual (Base .__optional_keys__ , frozenset ({}))
4256+         self .assertEqual (Base .__readonly_keys__ , frozenset ({}))
4257+         self .assertEqual (Base .__mutable_keys__ , frozenset ({}))
4258+         self .assertEqual (Base .__extra_items__ , ReadOnly [Union [str , None ]])
4259+ 
4260+         self .assertEqual (Child .__required_keys__ , frozenset ({'a' , "__extra_items__" }))
4261+         self .assertEqual (Child .__optional_keys__ , frozenset ({}))
4262+         self .assertEqual (Child .__readonly_keys__ , frozenset ({}))
4263+         self .assertEqual (Child .__mutable_keys__ , frozenset ({'a' , "__extra_items__" }))
4264+         self .assertEqual (Child .__extra_items__ , ReadOnly [Union [str , None ]])
4265+ 
4266+         self .assertEqual (GrandChild .__required_keys__ , frozenset ({'a' , "__extra_items__" }))
4267+         self .assertEqual (GrandChild .__optional_keys__ , frozenset ({}))
4268+         self .assertEqual (GrandChild .__readonly_keys__ , frozenset ({}))
4269+         self .assertEqual (GrandChild .__mutable_keys__ , frozenset ({'a' , "__extra_items__" }))
4270+         self .assertEqual (GrandChild .__extra_items__ , str )
4271+ 
4272+         self .assertEqual (Base .__annotations__ , {})
4273+         self .assertEqual (Child .__annotations__ , {"__extra_items__" : int , "a" : int })
4274+         self .assertEqual (GrandChild .__annotations__ , {"__extra_items__" : int , "a" : int })
4275+ 
4276+         self .assertTrue (Base .__closed__ )
4277+         self .assertFalse (Child .__closed__ )
4278+         self .assertTrue (GrandChild .__closed__ )
4279+     
4280+     def  test_absent_extra_items (self ):
4281+         class  Base (TypedDict ):
4282+             a : int 
4283+         
4284+         class  ChildA (Base , closed = True ):
4285+             ...
4286+ 
4287+         class  ChildB (Base , closed = True ):
4288+             __extra_items__ : None 
4289+         
4290+         self .assertNotIn ("__extra_items__" , Base .__dict__ )
4291+         self .assertIn ("__extra_items__" , ChildA .__dict__ )
4292+         self .assertIn ("__extra_items__" , ChildB .__dict__ )
4293+         self .assertEqual (ChildA .__extra_items__ , Never )
4294+         self .assertEqual (ChildB .__extra_items__ , type (None ))
41804295
41814296
41824297class  AnnotatedTests (BaseTestCase ):
0 commit comments