@@ -155,6 +155,7 @@ def to_json_plotly(plotly_object, pretty=False, engine=None):
155155 elif engine == "msgspec" :
156156 JsonConfig .validate_msgspec ()
157157 msgspec = get_module ("msgspec" , should_load = True )
158+ np = modules ["np" ]
158159 pd = modules ["pd" ]
159160
160161 def enc_hook (value ):
@@ -171,6 +172,8 @@ def enc_hook(value):
171172 raise TypeError (
172173 f"Type is not JSON serializable: { type (value ).__name__ } "
173174 )
175+ if np is not None and isinstance (value , np .datetime64 ) and np .isnat (value ):
176+ return None
174177 if pd is not None :
175178 if value is pd .NaT :
176179 return None
@@ -197,7 +200,16 @@ def enc_hook(value):
197200 encoder = msgspec .json .Encoder (enc_hook = enc_hook , decimal_format = "number" )
198201 try :
199202 out = encoder .encode (plotly_object )
200- except (TypeError , ValueError , OverflowError , msgspec .EncodeError ):
203+ # msgspec writes Decimal as is, so a NaN or Infinity value or a
204+ # Decimal dict key gives invalid JSON. Checking the syntax is cheap.
205+ msgspec .json .decode (out , type = msgspec .Raw )
206+ except (
207+ TypeError ,
208+ ValueError ,
209+ OverflowError ,
210+ RecursionError ,
211+ msgspec .MsgspecError ,
212+ ):
201213 # Errors and values msgspec rejects come out as with the json engine
202214 return to_json_plotly (plotly_object , pretty = pretty , engine = "json" )
203215 if pretty :
@@ -430,7 +442,12 @@ def from_json_plotly(value, engine=None):
430442 value_dict = get_module ("orjson" , should_load = True ).loads (value )
431443 elif engine == "msgspec" :
432444 JsonConfig .validate_msgspec ()
433- value_dict = get_module ("msgspec" , should_load = True ).json .decode (value )
445+ msgspec = get_module ("msgspec" , should_load = True )
446+ try :
447+ value_dict = msgspec .json .decode (value )
448+ except (ValueError , msgspec .MsgspecError ):
449+ # NaN and Infinity literals, numbers out of float range
450+ value_dict = from_json_plotly (value , engine = "json" )
434451 else :
435452 # decode bytes to str for built-in json module
436453 if isinstance (value , bytes ):
0 commit comments