Skip to content

Commit

Permalink
Cherry pick #255
Browse files Browse the repository at this point in the history
  • Loading branch information
wyfo committed Dec 2, 2021
1 parent 62eb2c9 commit b07243f
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 6 deletions.
19 changes: 14 additions & 5 deletions apischema/serialization/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,14 @@ class PassThroughOptions:
any: bool = False
collections: bool = False
enums: bool = False
tuple: bool = False
types: CollectionOrPredicate[AnyType] = ()

def __post_init__(self):
if isinstance(self.types, Collection) and not isinstance(self.types, tuple):
object.__setattr__(self, "types", tuple(self.types))
if self.collections and not self.tuple:
object.__setattr__(self, "tuple", True)


@dataclass
Expand Down Expand Up @@ -213,10 +216,14 @@ def collection(

method: SerializationMethod
if value_method is not IDENTITY_METHOD:
return CollectionMethod(value_method)
elif issubclass(cls, (list, tuple)) or (
self.pass_through_options.collections
and not issubclass(cls, collections.abc.Set)
method = CollectionMethod(value_method)
elif (
issubclass(cls, list)
or (self.pass_through_options.tuple and issubclass(cls, tuple))
or (
self.pass_through_options.collections
and not issubclass(cls, collections.abc.Set)
)
):
method = IDENTITY_METHOD
else:
Expand Down Expand Up @@ -341,7 +348,9 @@ def subprimitive(self, cls: Type, superclass: Type) -> SerializationMethod:
def tuple(self, types: Sequence[AnyType]) -> SerializationMethod:
elt_methods = tuple(map(self.visit, types))
method: SerializationMethod
if all(method is IDENTITY_METHOD for method in elt_methods):
if self.pass_through_options.tuple and all(
method is IDENTITY_METHOD for method in elt_methods
):
method = IDENTITY_METHOD
else:
method = TupleMethod(elt_methods)
Expand Down
2 changes: 1 addition & 1 deletion docs/de_serialization.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Deserialization performs a validation of data, based on typing annotations and o

### Allowed types

In some case, e.g. a MessagePack load with raw bytes inside, some data will have other type than
In some case, e.g. MessagePack loading with raw bytes inside, some data will have other type than
JSON primitive ones. These types can be allowed using `allowed_types` parameter; it must be collection of classes, or a predicate.

Only non JSON primitive classes can be allowed, because *apischema* relies on a type check with `isinstance` to skip deserialization. That exclude `NewType` but also `TypeDict`.
Expand Down
7 changes: 7 additions & 0 deletions docs/performance_and_benchmark.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ But, most of the time, collections runtime types are `list`/`dict`, so others ca

#### `enums` — pass through enums

#### `tuple` — pass through `tuple`

Even if `tuple` is often supported by JSON serializers, if this options is not enabled, tuples will be serialized as lists. It also allows easier test writing for example.

!!! note
`collections=True` implies `tuple=True`;

#### `types` — pass through arbitrary types

Either a collection of types, or a predicate to determine if type has to be passed through.
Expand Down

0 comments on commit b07243f

Please sign in to comment.