@@ -1229,3 +1229,115 @@ class MixedStruct:
12291229 annotated_float = 2.0 ,
12301230 )
12311231 validate_full_roundtrip (instance , MixedStruct )
1232+
1233+
1234+ def test_roundtrip_struct_to_dict_binding () -> None :
1235+ """Test struct -> dict binding with Any annotation."""
1236+
1237+ @dataclass
1238+ class SimpleStruct :
1239+ name : str
1240+ value : int
1241+ price : float
1242+
1243+ instance = SimpleStruct ("test" , 42 , 3.14 )
1244+ expected_dict = {"name" : "test" , "value" : 42 , "price" : 3.14 }
1245+
1246+ # Test Any annotation
1247+ validate_full_roundtrip (instance , SimpleStruct , (expected_dict , Any ))
1248+
1249+
1250+ def test_roundtrip_struct_to_dict_explicit () -> None :
1251+ """Test struct -> dict binding with explicit dict annotations."""
1252+
1253+ @dataclass
1254+ class Product :
1255+ id : str
1256+ name : str
1257+ price : float
1258+ active : bool
1259+
1260+ instance = Product ("P1" , "Widget" , 29.99 , True )
1261+ expected_dict = {"id" : "P1" , "name" : "Widget" , "price" : 29.99 , "active" : True }
1262+
1263+ # Test explicit dict annotations
1264+ validate_full_roundtrip (
1265+ instance , Product , (expected_dict , dict ), (expected_dict , dict [str , Any ])
1266+ )
1267+
1268+
1269+ def test_roundtrip_struct_to_dict_with_none_annotation () -> None :
1270+ """Test struct -> dict binding with None annotation."""
1271+
1272+ @dataclass
1273+ class Config :
1274+ host : str
1275+ port : int
1276+ debug : bool
1277+
1278+ instance = Config ("localhost" , 8080 , True )
1279+ expected_dict = {"host" : "localhost" , "port" : 8080 , "debug" : True }
1280+
1281+ # Test None annotation (should be treated as Any)
1282+ validate_full_roundtrip (instance , Config , (expected_dict , None ))
1283+
1284+
1285+ def test_roundtrip_struct_to_dict_nested () -> None :
1286+ """Test struct -> dict binding with nested structs."""
1287+
1288+ @dataclass
1289+ class Address :
1290+ street : str
1291+ city : str
1292+
1293+ @dataclass
1294+ class Person :
1295+ name : str
1296+ age : int
1297+ address : Address
1298+
1299+ address = Address ("123 Main St" , "Anytown" )
1300+ person = Person ("John" , 30 , address )
1301+ expected_dict = {
1302+ "name" : "John" ,
1303+ "age" : 30 ,
1304+ "address" : {"street" : "123 Main St" , "city" : "Anytown" },
1305+ }
1306+
1307+ # Test nested struct conversion
1308+ validate_full_roundtrip (person , Person , (expected_dict , dict [str , Any ]))
1309+
1310+
1311+ def test_roundtrip_struct_to_dict_with_list () -> None :
1312+ """Test struct -> dict binding with list fields."""
1313+
1314+ @dataclass
1315+ class Team :
1316+ name : str
1317+ members : list [str ]
1318+ active : bool
1319+
1320+ instance = Team ("Dev Team" , ["Alice" , "Bob" , "Charlie" ], True )
1321+ expected_dict = {
1322+ "name" : "Dev Team" ,
1323+ "members" : ["Alice" , "Bob" , "Charlie" ],
1324+ "active" : True ,
1325+ }
1326+
1327+ validate_full_roundtrip (instance , Team , (expected_dict , dict ))
1328+
1329+
1330+ def test_roundtrip_namedtuple_to_dict_binding () -> None :
1331+ """Test NamedTuple -> dict binding."""
1332+
1333+ class Point (NamedTuple ):
1334+ x : float
1335+ y : float
1336+ z : float
1337+
1338+ instance = Point (1.0 , 2.0 , 3.0 )
1339+ expected_dict = {"x" : 1.0 , "y" : 2.0 , "z" : 3.0 }
1340+
1341+ validate_full_roundtrip (
1342+ instance , Point , (expected_dict , dict ), (expected_dict , Any )
1343+ )
0 commit comments