dataclasses-avroschema icon indicating copy to clipboard operation
dataclasses-avroschema copied to clipboard

`AvroBaseModel` not working for union schema with repeating field names

Open tebartsch opened this issue 2 years ago • 2 comments

Describe the bug When using two different schemas with the same field name the union field type does not work correctly for AvroBaseModel.

To Reproduce The following script

import typing
from dataclasses_avroschema.avrodantic import AvroBaseModel


class A1(AvroBaseModel):
    i: int


class A2(AvroBaseModel):
    i: int


class B(AvroBaseModel):
    a: typing.Union[A1, A2]


if __name__ == "__main__":
    a1 = A1(i=0)
    a2 = A2(i=0)

    b1 = B(a=a1)
    b2 = B(a=a2)

    assert isinstance(b1.a, A1), f"{type(b1.a)} != {A1}"
    assert isinstance(b2.a, A2), f"{type(b2.a)} != {A2}"

yields

Traceback (most recent call last):
  File "/home/tbartsch/test/new-avro-file.py", line 25, in <module>
    assert isinstance(b2.a, A2), f"{type(b2.a)} != {A2}"
AssertionError: <class '__main__.A1'> != <class '__main__.A2'>

Expected behavior The assertion above should be true.

tebartsch avatar Oct 01 '22 01:10 tebartsch

Hi @tilmann-bartsch

It looks like it is a pydantic bug. I have opened an issue

Using AvroModel and dataclasses for the instance creation it works as expected:

import typing
from dataclasses import dataclass

from dataclasses_avroschema import AvroModel


@dataclass
class A1(AvroModel):
    i: int


@dataclass
class A2(AvroModel):
    i: int


@dataclass
class B(AvroModel):
    a: typing.Union[A1, A2]


if __name__ == "__main__":
    a1 = A1(i=0)
    a2 = A2(i=0)

    b1 = B(a=a1)
    b2 = B(a=a2)

    assert isinstance(b1.a, A1), f"{type(b1.a)} != {A1}"
    assert isinstance(b2.a, A2), f"{type(b2.a)} != {A2}"

marcosschroh avatar Oct 07 '22 09:10 marcosschroh

pydantic maintainer reply: This is a known problem about unions coercing the first possible type, unions will get smarter in v2.. So, I think you will have to wait until the pydantic v2 is released and in the mean time use dataclasses

marcosschroh avatar Oct 07 '22 10:10 marcosschroh

Now you can use pydantic v2 which is smarter . Closed by https://github.com/marcosschroh/dataclasses-avroschema/pull/455.

marcosschroh avatar Nov 03 '23 15:11 marcosschroh