| 2193 | |
| 2194 | @mapcls_from_attributes_and_array_like |
| 2195 | def test_generic_struct_union(self, mapcls, from_attributes, array_like): |
| 2196 | class Test1(Struct, Generic[T], tag=True, array_like=array_like): |
| 2197 | a: Union[T, None] |
| 2198 | b: int |
| 2199 | |
| 2200 | class Test2(Struct, Generic[T], tag=True, array_like=array_like): |
| 2201 | x: T |
| 2202 | y: int |
| 2203 | |
| 2204 | typ = Union[Test1[T], Test2[T]] |
| 2205 | |
| 2206 | msg1 = Test1(1, 2) |
| 2207 | s1 = mapcls(type="Test1", a=1, b=2) |
| 2208 | msg2 = Test2("three", 4) |
| 2209 | s2 = mapcls(type="Test2", x="three", y=4) |
| 2210 | msg3 = Test1(None, 4) |
| 2211 | s3 = mapcls(type="Test1", a=None, b=4) |
| 2212 | |
| 2213 | assert convert(s1, typ, from_attributes=from_attributes) == msg1 |
| 2214 | assert convert(s2, typ, from_attributes=from_attributes) == msg2 |
| 2215 | assert convert(s3, typ, from_attributes=from_attributes) == msg3 |
| 2216 | |
| 2217 | assert convert(s1, typ[int], from_attributes=from_attributes) == msg1 |
| 2218 | assert convert(s3, typ[int], from_attributes=from_attributes) == msg3 |
| 2219 | assert convert(s2, typ[str], from_attributes=from_attributes) == msg2 |
| 2220 | assert convert(s3, typ[str], from_attributes=from_attributes) == msg3 |
| 2221 | |
| 2222 | with pytest.raises(ValidationError) as rec: |
| 2223 | convert(s1, typ[str], from_attributes=from_attributes) |
| 2224 | assert "Expected `str | null`, got `int`" in str(rec.value) |
| 2225 | loc = "$[1]" if array_like and not from_attributes else "$.a" |
| 2226 | assert loc in str(rec.value) |
| 2227 | |
| 2228 | with pytest.raises(ValidationError) as rec: |
| 2229 | convert(s2, typ[int], from_attributes=from_attributes) |
| 2230 | assert "Expected `int`, got `str`" in str(rec.value) |
| 2231 | loc = "$[1]" if array_like and not from_attributes else "$.x" |
| 2232 | assert loc in str(rec.value) |
| 2233 | |
| 2234 | |
| 2235 | class TestStructPostInit: |