@@ -2233,3 +2233,77 @@ def test_match(self) -> None:
2233
2233
self .assertIsNone (y )
2234
2234
case _:
2235
2235
self .fail ("Expected match, got none." )
2236
+
2237
+ def test_fbthrift_copy_from (self ) -> None :
2238
+ """
2239
+ `lhs.fbthrift_copy_from(rhs)` copies the content of the `rhs` struct
2240
+ into the lhs struct. It is semantically equivalent to assigning each
2241
+ field of `rhs` to `lhs`."
2242
+ """
2243
+ # Struct with primitive fields
2244
+ s1 = TestStructAllThriftPrimitiveTypesMutable (
2245
+ unqualified_bool = True ,
2246
+ optional_byte = 0 ,
2247
+ unqualified_i16 = 1 ,
2248
+ optional_i32 = 2 ,
2249
+ unqualified_i64 = 3 ,
2250
+ optional_float = 4.0 ,
2251
+ unqualified_double = 5.0 ,
2252
+ optional_string = "abc" ,
2253
+ )
2254
+
2255
+ s2 = TestStructAllThriftPrimitiveTypesMutable ()
2256
+ self .assertNotEqual (s1 , s2 )
2257
+ s2 .fbthrift_copy_from (s1 )
2258
+ self .assertEqual (s1 , s2 )
2259
+
2260
+ # Struct with container fields
2261
+ s3 = TestStructAllThriftContainerTypesMutable (
2262
+ unqualified_list_i32 = to_thrift_list ([1 , 2 , 3 ]),
2263
+ optional_set_string = to_thrift_set ({"a" , "b" , "c" }),
2264
+ unqualified_map_string_i32 = to_thrift_map ({"a" : 1 , "b" : 2 }),
2265
+ )
2266
+
2267
+ s4 = TestStructAllThriftContainerTypesMutable ()
2268
+ self .assertNotEqual (s3 , s4 )
2269
+ s4 .fbthrift_copy_from (s3 )
2270
+ self .assertEqual (s3 , s4 )
2271
+
2272
+ # Container assignment is refernce semantics, after `fbthrift_copy_from()`
2273
+ # s3 and s4 container fields are the "same" containers.
2274
+ self .assertEqual ([1 , 2 , 3 ], s3 .unqualified_list_i32 )
2275
+ self .assertEqual ([1 , 2 , 3 ], s4 .unqualified_list_i32 )
2276
+
2277
+ s3 .unqualified_list_i32 .append (4 )
2278
+
2279
+ self .assertEqual ([1 , 2 , 3 , 4 ], s3 .unqualified_list_i32 )
2280
+ self .assertEqual ([1 , 2 , 3 , 4 ], s4 .unqualified_list_i32 )
2281
+
2282
+ # Struct with struct fields
2283
+ n2 = TestStructNested_2_Mutable (i32_field = 2 )
2284
+ n1 = TestStructNested_1_Mutable (i32_field = 3 , nested_2 = n2 )
2285
+ s5 = TestStructNested_0_Mutable (i32_field = 5 , nested_1 = n1 )
2286
+
2287
+ s6 = TestStructNested_0_Mutable ()
2288
+ self .assertNotEqual (s5 , s6 )
2289
+ s6 .fbthrift_copy_from (s5 )
2290
+ self .assertEqual (s5 , s6 )
2291
+
2292
+ # Struct assignment is refernce semantics, after `fbthrift_copy_from()`
2293
+ # s5 and s4 struct fields are the "same" structs.
2294
+ self .assertEqual (3 , s5 .nested_1 .i32_field )
2295
+ self .assertEqual (3 , s6 .nested_1 .i32_field )
2296
+
2297
+ s5 .nested_1 .i32_field = 33
2298
+
2299
+ self .assertEqual (33 , s5 .nested_1 .i32_field )
2300
+ self .assertEqual (33 , s6 .nested_1 .i32_field )
2301
+
2302
+ # `lhs` and `rhs` must be the same type
2303
+ s7 = TestStructAllThriftPrimitiveTypesMutable ()
2304
+ with self .assertRaisesRegex (
2305
+ TypeError ,
2306
+ "Cannot copy from.*TestStructAllThriftContainerTypes.*to"
2307
+ ".*TestStructAllThriftPrimitiveTypes" ,
2308
+ ):
2309
+ s7 .fbthrift_copy_from (TestStructAllThriftContainerTypesMutable ())
0 commit comments