1212
1313Serialization/deserialization
1414-----------------------------
15+
16+ .. autoclass:: SerializationKey
17+ .. autoclass:: SerializedContainer
1518.. autofunction:: is_array_container_type
1619.. autofunction:: serialize_container
1720.. autofunction:: deserialize_container
3942.. class:: ArrayOrContainerT
4043
4144 :canonical: arraycontext.ArrayOrContainerT
45+
46+ .. class:: SerializationKey
47+
48+ :canonical: arraycontext.SerializationKey
49+
50+ .. class:: SerializedContainer
51+
52+ :canonical: arraycontext.SerializedContainer
4253"""
4354
4455from __future__ import annotations
6980"""
7081
7182from functools import singledispatch
72- from typing import TYPE_CHECKING , Any , Iterable , Optional , Protocol , Tuple , TypeVar
83+ from typing import (
84+ TYPE_CHECKING ,
85+ Any ,
86+ Hashable ,
87+ Iterable ,
88+ Optional ,
89+ Protocol ,
90+ Sequence ,
91+ Tuple ,
92+ TypeVar ,
93+ )
7394
7495# For use in singledispatch type annotations, because sphinx can't figure out
7596# what 'np' is.
7697import numpy
7798import numpy as np
99+ from typing_extensions import TypeAlias
78100
79101from arraycontext .context import ArrayContext
80102
@@ -142,23 +164,27 @@ class NotAnArrayContainerError(TypeError):
142164 """:class:`TypeError` subclass raised when an array container is expected."""
143165
144166
167+ SerializationKey : TypeAlias = Hashable
168+ SerializedContainer : TypeAlias = Sequence [Tuple [SerializationKey , "ArrayOrContainer" ]]
169+
170+
145171@singledispatch
146172def serialize_container (
147- ary : ArrayContainer ) -> Iterable [ Tuple [ Any , ArrayOrContainer ]] :
148- r"""Serialize the array container into an iterable over its components.
173+ ary : ArrayContainer ) -> SerializedContainer :
174+ r"""Serialize the array container into a sequence over its components.
149175
150176 The order of the components and their identifiers are entirely under
151177 the control of the container class. However, the order is required to be
152178 deterministic, i.e. two calls to :func:`serialize_container` on
153179 array containers of the same types with the same number of
154- sub-arrays must result in an iterable with the keys in the same
180+ sub-arrays must result in a sequence with the keys in the same
155181 order.
156182
157183 If *ary* is mutable, the serialization function is not required to ensure
158184 that the serialization result reflects the array state at the time of the
159185 call to :func:`serialize_container`.
160186
161- :returns: an :class:`Iterable ` of 2-tuples where the first
187+ :returns: a :class:`Sequence ` of 2-tuples where the first
162188 entry is an identifier for the component and the second entry
163189 is an array-like component of the :class:`ArrayContainer`.
164190 Components can themselves be :class:`ArrayContainer`\ s, allowing
@@ -172,13 +198,13 @@ def serialize_container(
172198@singledispatch
173199def deserialize_container (
174200 template : ArrayContainerT ,
175- iterable : Iterable [ Tuple [ Any , Any ]] ) -> ArrayContainerT :
176- """Deserialize an iterable into an array container.
201+ serialized : SerializedContainer ) -> ArrayContainerT :
202+ """Deserialize a sequence into an array container following a *template* .
177203
178204 :param template: an instance of an existing object that
179205 can be used to aid in the deserialization. For a similar choice
180206 see :attr:`~numpy.class.__array_finalize__`.
181- :param iterable: an iterable that mirrors the output of
207+ :param serialized: a sequence that mirrors the output of
182208 :meth:`serialize_container`.
183209 """
184210 raise NotAnArrayContainerError (
@@ -242,7 +268,7 @@ def get_container_context_opt(ary: ArrayContainer) -> Optional[ArrayContext]:
242268
243269@serialize_container .register (np .ndarray )
244270def _serialize_ndarray_container (
245- ary : numpy .ndarray ) -> Iterable [ Tuple [ Any , ArrayOrContainer ]] :
271+ ary : numpy .ndarray ) -> SerializedContainer :
246272 if ary .dtype .char != "O" :
247273 raise NotAnArrayContainerError (
248274 f"cannot serialize '{ type (ary ).__name__ } ' with dtype '{ ary .dtype } '" )
@@ -256,20 +282,20 @@ def _serialize_ndarray_container(
256282 for j in range (ary .shape [1 ])
257283 ]
258284 else :
259- return np .ndenumerate (ary )
285+ return list ( np .ndenumerate (ary ) )
260286
261287
262288@deserialize_container .register (np .ndarray )
263289# https://github.com/python/mypy/issues/13040
264290def _deserialize_ndarray_container ( # type: ignore[misc]
265291 template : numpy .ndarray ,
266- iterable : Iterable [ Tuple [ Any , ArrayOrContainer ]] ) -> numpy .ndarray :
292+ serialized : SerializedContainer ) -> numpy .ndarray :
267293 # disallow subclasses
268294 assert type (template ) is np .ndarray
269295 assert template .dtype .char == "O"
270296
271297 result = type (template )(template .shape , dtype = object )
272- for i , subary in iterable :
298+ for i , subary in serialized :
273299 result [i ] = subary
274300
275301 return result
0 commit comments