@@ -162,7 +162,7 @@ class Point2D(typing.TypedDict):
162162 ],
163163)
164164def test_coerce_from_type_hints (value : Any , type_hint : Any , expected : Any ):
165- result = _coerce (value , type_hint , {}, "0" , value )
165+ result = _coerce (value , type_hint , {}, "0" , type ( value ) )
166166 assert type (result ) is type (expected )
167167 assert result == expected
168168
@@ -545,6 +545,30 @@ def test_recursive_decode():
545545 assert x .children [0 ].children [0 ].name == "l3"
546546
547547
548+ def test_nested_recursive_decode ():
549+ @dataclass
550+ class Config :
551+ x : RecursiveType
552+
553+ c = decode (
554+ Config ,
555+ {
556+ "x" : {
557+ "name" : "l1" ,
558+ "children" : [{"name" : "l2" , "children" : [{"name" : "l3" , "children" : None }]}],
559+ }
560+ },
561+ )
562+ assert isinstance (c , Config )
563+ assert c .x .name == "l1"
564+ assert c .x .children is not None
565+ assert isinstance (c .x .children [0 ], RecursiveType )
566+ assert c .x .children [0 ].name == "l2"
567+ assert c .x .children [0 ].children is not None
568+ assert isinstance (c .x .children [0 ].children [0 ], RecursiveType )
569+ assert c .x .children [0 ].children [0 ].name == "l3"
570+
571+
548572@dataclass
549573class RecursiveType2 :
550574 name : str
@@ -568,13 +592,36 @@ def test_recursive_decode_with_str_forward_reference():
568592 assert x .children [0 ].children [0 ].name == "l3"
569593
570594
595+ def test_nested_recursive_decode_with_str_forward_reference ():
596+ @dataclass
597+ class Config :
598+ x : RecursiveType2
599+
600+ c = decode (
601+ Config ,
602+ {
603+ "x" : {
604+ "name" : "l1" ,
605+ "children" : [{"name" : "l2" , "children" : [{"name" : "l3" , "children" : None }]}],
606+ }
607+ },
608+ )
609+ assert isinstance (c , Config )
610+ assert c .x .name == "l1"
611+ assert c .x .children is not None
612+ assert isinstance (c .x .children [0 ], RecursiveType2 )
613+ assert c .x .children [0 ].name == "l2"
614+ assert c .x .children [0 ].children is not None
615+ assert isinstance (c .x .children [0 ].children [0 ], RecursiveType2 )
616+ assert c .x .children [0 ].children [0 ].name == "l3"
617+
618+
571619@dataclass
572620class RecursiveTypeWithSelf :
573621 name : str
574622 children : list [Self ] | None
575623
576624
577- # @pytest.mark.xfail
578625def test_recursive_decode_with_self_type ():
579626 x = decode (
580627 RecursiveTypeWithSelf ,
@@ -590,3 +637,27 @@ def test_recursive_decode_with_self_type():
590637 assert x .children [0 ].children is not None
591638 assert isinstance (x .children [0 ].children [0 ], RecursiveTypeWithSelf )
592639 assert x .children [0 ].children [0 ].name == "l3"
640+
641+
642+ def test_nested_recursive_decode_with_self_type ():
643+ @dataclass
644+ class Config :
645+ x : RecursiveTypeWithSelf
646+
647+ c = decode (
648+ Config ,
649+ {
650+ "x" : {
651+ "name" : "l1" ,
652+ "children" : [{"name" : "l2" , "children" : [{"name" : "l3" , "children" : None }]}],
653+ }
654+ },
655+ )
656+ assert isinstance (c , Config )
657+ assert c .x .name == "l1"
658+ assert c .x .children is not None
659+ assert isinstance (c .x .children [0 ], RecursiveTypeWithSelf )
660+ assert c .x .children [0 ].name == "l2"
661+ assert c .x .children [0 ].children is not None
662+ assert isinstance (c .x .children [0 ].children [0 ], RecursiveTypeWithSelf )
663+ assert c .x .children [0 ].children [0 ].name == "l3"
0 commit comments