wyfo / apischema

JSON (de)serialization, GraphQL and JSON schema generation using Python typing.

Home Page:https://wyfo.github.io/apischema/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Fix frozenset deserialization

pchanial opened this issue · comments

AbstractSet and FrozenSet are not deserialized in frozensets.

from typing import AbstractSet, FrozenSet
from apischema import deserialize
assert type(deserialize(AbstractSet[int], [1, 2, 3])) is set
assert type(deserialize(FrozenSet[int], [1, 2, 3])) is set

PR to follow

Hi, thank you for spotting this bug!

Actually, the true bug is the lack of proper support of typing.FrozenSet/ frozenset. However, having AbstractSet/collections.abc.Set being deserialized as set is not really an issue, as the type constraint is respected.

To give you some context, as you have dug into apischema tests, you have noticed this test case: (AbstractSet, frozenset([0, SimpleDataclass(0)])),; there was indeed a time where AbstractSet was deserialized as frozenset, but not only: Sequence was also deserialized as tuple, and even Maping was deserialized as MappingProxyType.
However, as mentioned above, using set for AbstractSet is still correct, as well as using list for Sequence. And it's not only correct, but also faster to deserialize — immutable types requires to be deserialized as list before to be converted — and can be more intuitive for some people.

That's why, if there is indeed a bug with frozenset, I don't want AbstractSet behavior to be changed for now, because of the performance impact; I will create an other issue about this specific behavior (abstract container deserialization as immutable instance).

P.S. I've checked the history and indeed, AbstractSet deserialization change to set instead of frozenset was indeed about performance. Also, in the PR (#191), I'd fixed Sequence deserialization to list but forgot to modify AbstractSet.

Interesting discussion. But now I wonder if it makes sense to use an abstract type as a target type for deserialization. They are not enough constrained by definition. What would be the consequences of only supporting concrete classes ? It looks like a source of confusion that may bite again.