1111import json
1212from typing import Any
1313
14- from ..shm import NDArray , SharedMemory
15-
1614Args = dict [str , Any ]
1715
16+ _encoders : dict [type , tuple [str , Any ]] = {}
17+ _decoders : dict [str , Any ] = {}
18+
19+
20+ def register (obj_type : type , appose_type : str , encoder , decoder ) -> None :
21+ """
22+ Register encoder and decoder functions for a custom Appose type.
23+
24+ When encoding, if an object is an instance of ``obj_type``, ``encoder``
25+ is called with the object and its return value is wrapped as
26+ ``{"appose_type": appose_type, "data": <encoded>}``.
27+
28+ When decoding, if a JSON object has the given ``appose_type``, ``decoder``
29+ is called with the ``"data"`` field value and should return the
30+ reconstructed Python object.
31+
32+ :param obj_type: The Python type to encode.
33+ :param appose_type: The ``appose_type`` string used on the wire.
34+ :param encoder: Callable ``(obj) -> JSON-compatible value``.
35+ :param decoder: Callable ``(data) -> obj``.
36+ """
37+ _encoders [obj_type ] = (appose_type , encoder )
38+ _decoders [appose_type ] = decoder
39+
40+
1841# Flag indicating whether this process is running as an Appose worker.
1942# Set to True by python_worker.Worker.__init__().
2043_worker_mode = False
@@ -36,8 +59,9 @@ def decode(the_json: str) -> Args:
3659
3760class _ApposeJSONEncoder (json .JSONEncoder ):
3861 def default (self , obj ):
39- if hasattr (obj , "for_json" ):
40- return obj .for_json ()
62+ for obj_type , (appose_type , encoder ) in _encoders .items ():
63+ if isinstance (obj , obj_type ):
64+ return {"appose_type" : appose_type , ** encoder (obj )}
4165
4266 # If in worker mode and object is not JSON-serializable,
4367 # auto-export it and return a worker_object reference.
@@ -60,17 +84,13 @@ def default(self, obj):
6084
6185def _appose_object_hook (obj : dict ):
6286 atype = obj .get ("appose_type" )
63- if atype == "shm" :
64- # Attach to existing shared memory block.
65- return SharedMemory (name = (obj ["name" ]), rsize = (obj ["rsize" ]))
66- elif atype == "ndarray" :
67- return NDArray (obj ["dtype" ], obj ["shape" ], obj ["shm" ])
68- elif atype == "worker_object" :
87+ if atype == "worker_object" :
6988 # Keep worker_object dicts as-is for now.
7089 # They will be converted to proxies by proxify_worker_objects().
7190 return obj
72- else :
73- return obj
91+ if atype in _decoders :
92+ return _decoders [atype ](obj )
93+ return obj
7494
7595
7696def proxify_worker_objects (data : Any , service : Any ) -> Any :
0 commit comments