konradhalas / dacite

Simple creation of data classes from dictionaries.
MIT License
1.76k stars 106 forks source link

Caching can lead to runtime errors due to subtle differences between `T | V` and `Union[T, V]` #261

Closed russellp17 closed 1 month ago

russellp17 commented 1 month ago

Describe the bug

Potentially related to https://github.com/konradhalas/dacite/issues/180

I ran into some errors recently after converting types from Union[T, V] -> T | V style and found that there is some subtle behavior with caching and the differences between these types that can lead to errors.

The two types hash to the same value:

>>> hash(str | None)
976962247394846029
>>> hash(Union[str, None])
976962247394846029

even though only the Union style defines its __origin__ attribute:

>>> (typing.Union[str, None]).__origin__
typing.Union
>>> (str | None).__origin__
AttributeError: 'types.UnionType' object has no attribute '__origin__'

To Reproduce

This can cause an error when dacite.types.is_generic is first called with a Union style type and then another function like dacite.types.is_generic_collection is called with the equivalent pipe style type:

>>> dacite.types.is_generic(Union[str, None])
True
>>> dacite.types.is_generic_collection(str | None)
...
AttributeError: 'types.UnionType' object has no attribute '__origin__'

Note that swapping the ordering of the type styles does not cause an error:

>>> dacite.types.is_generic(str | None)
False
>>> dacite.types.is_generic_collection(Union[str, None])
False

In my application call, I'm mostly just calling dacite.from_dict had trouble reproing from that higher-level function although saw this exception pop up in production usage.

Expected behavior

Expect that the two type styles for unions should be fully interchangeable and not lead to runtime errors.

Environment

Additional context Add any other context about the problem here.

russellp17 commented 1 month ago

ah this looks to be a dupe of https://github.com/konradhalas/dacite/issues/236 and should be fixed with https://github.com/konradhalas/dacite/pull/258

Sorry for the spam