33# Copyright (c) IPython Development Team.
44# Distributed under the terms of the Modified BSD License.
55
6- import math
7- import numbers
86import re
9- import types
10- from binascii import b2a_base64
11- from datetime import date , datetime
7+ from datetime import datetime
128
139from jupyter_client ._version import version_info as jupyter_client_version
1410
5248def encode_images (format_dict ):
5349 """b64-encodes images in a displaypub format dict
5450
55- Perhaps this should be handled in json_clean itself?
56-
5751 Parameters
5852 ----------
5953 format_dict : dict
@@ -72,92 +66,3 @@ def encode_images(format_dict):
7266 # where bytes objects always represent binary data and thus
7367 # base64-encoded.
7468 return format_dict
75-
76-
77- def json_clean (obj ): # pragma: no cover
78- """Deprecated, this is a no-op for jupyter-client>=7.
79-
80- Clean an object to ensure it's safe to encode in JSON.
81-
82- Atomic, immutable objects are returned unmodified. Sets and tuples are
83- converted to lists, lists are copied and dicts are also copied.
84-
85- Note: dicts whose keys could cause collisions upon encoding (such as a dict
86- with both the number 1 and the string '1' as keys) will cause a ValueError
87- to be raised.
88-
89- Parameters
90- ----------
91- obj : any python object
92-
93- Returns
94- -------
95- out : object
96- A version of the input which will not cause an encoding error when
97- encoded as JSON. Note that this function does not *encode* its inputs,
98- it simply sanitizes it so that there will be no encoding errors later.
99-
100- """
101- if int (JUPYTER_CLIENT_MAJOR_VERSION ) >= 7 :
102- return obj
103-
104- # types that are 'atomic' and ok in json as-is.
105- atomic_ok = (str , type (None ))
106-
107- # containers that we need to convert into lists
108- container_to_list = (tuple , set , types .GeneratorType )
109-
110- # Since bools are a subtype of Integrals, which are a subtype of Reals,
111- # we have to check them in that order.
112-
113- if isinstance (obj , bool ):
114- return obj
115-
116- if isinstance (obj , numbers .Integral ):
117- # cast int to int, in case subclasses override __str__ (e.g. boost enum, #4598)
118- return int (obj )
119-
120- if isinstance (obj , numbers .Real ):
121- # cast out-of-range floats to their reprs
122- if math .isnan (obj ) or math .isinf (obj ):
123- return repr (obj )
124- return float (obj )
125-
126- if isinstance (obj , atomic_ok ):
127- return obj
128-
129- if isinstance (obj , bytes ):
130- # unanmbiguous binary data is base64-encoded
131- # (this probably should have happened upstream)
132- return b2a_base64 (obj ).decode ("ascii" )
133-
134- if isinstance (obj , container_to_list ) or (
135- hasattr (obj , "__iter__" ) and hasattr (obj , next_attr_name )
136- ):
137- obj = list (obj )
138-
139- if isinstance (obj , list ):
140- return [json_clean (x ) for x in obj ]
141-
142- if isinstance (obj , dict ):
143- # First, validate that the dict won't lose data in conversion due to
144- # key collisions after stringification. This can happen with keys like
145- # True and 'true' or 1 and '1', which collide in JSON.
146- nkeys = len (obj )
147- nkeys_collapsed = len (set (map (str , obj )))
148- if nkeys != nkeys_collapsed :
149- msg = (
150- "dict cannot be safely converted to JSON: "
151- "key collision would lead to dropped values"
152- )
153- raise ValueError (msg )
154- # If all OK, proceed by making the new dict that will be json-safe
155- out = {}
156- for k , v in obj .items ():
157- out [str (k )] = json_clean (v )
158- return out
159- if isinstance (obj , datetime | date ):
160- return obj .strftime (ISO8601 )
161-
162- # we don't understand it, it's probably an unserializable object
163- raise ValueError ("Can't clean for JSON: %r" % obj )
0 commit comments