@@ -4402,6 +4402,39 @@ class Cat(Animal):
44024402 'voice' : str ,
44034403 }
44044404
4405+ @skipIf (sys .version_info == (3 , 14 , 0 , "beta" , 1 ), "Broken on beta 1, fixed in beta 2" )
4406+ def test_inheritance_pep563 (self ):
4407+ def _make_td (future , class_name , annos , base , extra_names = None ):
4408+ lines = []
4409+ if future :
4410+ lines .append ('from __future__ import annotations' )
4411+ lines .append ('from typing import TypedDict' )
4412+ lines .append (f'class { class_name } ({ base } ):' )
4413+ for name , anno in annos .items ():
4414+ lines .append (f' { name } : { anno } ' )
4415+ code = '\n ' .join (lines )
4416+ ns = {** extra_names } if extra_names else {}
4417+ exec (code , ns )
4418+ return ns [class_name ]
4419+
4420+ for base_future in (True , False ):
4421+ for child_future in (True , False ):
4422+ with self .subTest (base_future = base_future , child_future = child_future ):
4423+ base = _make_td (
4424+ base_future , "Base" , {"base" : "int" }, "TypedDict"
4425+ )
4426+ if sys .version_info >= (3 , 14 ):
4427+ self .assertIsNotNone (base .__annotate__ )
4428+ child = _make_td (
4429+ child_future , "Child" , {"child" : "int" }, "Base" , {"Base" : base }
4430+ )
4431+ base_anno = typing .ForwardRef ("int" , module = "builtins" ) if base_future else int
4432+ child_anno = typing .ForwardRef ("int" , module = "builtins" ) if child_future else int
4433+ self .assertEqual (base .__annotations__ , {'base' : base_anno })
4434+ self .assertEqual (
4435+ child .__annotations__ , {'child' : child_anno , 'base' : base_anno }
4436+ )
4437+
44054438 def test_required_notrequired_keys (self ):
44064439 self .assertEqual (NontotalMovie .__required_keys__ ,
44074440 frozenset ({"title" }))
@@ -7014,6 +7047,7 @@ class Group(NamedTuple):
70147047 self .assertIs (type (a ), Group )
70157048 self .assertEqual (a , (1 , [2 ]))
70167049
7050+ @skipUnless (sys .version_info <= (3 , 15 ), "Behavior removed in 3.15" )
70177051 def test_namedtuple_keyword_usage (self ):
70187052 with self .assertWarnsRegex (
70197053 DeprecationWarning ,
@@ -7049,6 +7083,7 @@ def test_namedtuple_keyword_usage(self):
70497083 ):
70507084 NamedTuple ('Name' , None , x = int )
70517085
7086+ @skipUnless (sys .version_info <= (3 , 15 ), "Behavior removed in 3.15" )
70527087 def test_namedtuple_special_keyword_names (self ):
70537088 with self .assertWarnsRegex (
70547089 DeprecationWarning ,
@@ -7064,6 +7099,7 @@ def test_namedtuple_special_keyword_names(self):
70647099 self .assertEqual (a .typename , 'foo' )
70657100 self .assertEqual (a .fields , [('bar' , tuple )])
70667101
7102+ @skipUnless (sys .version_info <= (3 , 15 ), "Behavior removed in 3.15" )
70677103 def test_empty_namedtuple (self ):
70687104 expected_warning = re .escape (
70697105 "Failing to pass a value for the 'fields' parameter is deprecated "
0 commit comments