Skip to content

Commit a4ea628

Browse files
committed
Remove json_clean
1 parent c36de65 commit a4ea628

File tree

9 files changed

+41
-194
lines changed

9 files changed

+41
-194
lines changed

ipykernel/comm/comm.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from traitlets.config import LoggingConfigurable
99
from ipykernel.kernelbase import Kernel
1010

11-
from ipykernel.jsonutil import json_clean
1211
from traitlets import Instance, Unicode, Bytes, Bool, Dict, Any, default
1312

1413

@@ -62,10 +61,10 @@ def _publish_msg(self, msg_type, data=None, metadata=None, buffers=None, **keys)
6261
"""Helper for sending a comm message on IOPub"""
6362
data = {} if data is None else data
6463
metadata = {} if metadata is None else metadata
65-
content = json_clean(dict(data=data, comm_id=self.comm_id, **keys))
64+
content = dict(data=data, comm_id=self.comm_id, **keys)
6665
self.kernel.session.send(self.kernel.iopub_socket, msg_type,
6766
content,
68-
metadata=json_clean(metadata),
67+
metadata=metadata,
6968
parent=self.kernel.get_parent("shell"),
7069
ident=self.topic,
7170
buffers=buffers,

ipykernel/datapub.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212

1313
from traitlets.config import Configurable
1414
from traitlets import Instance, Dict, CBytes, Any
15-
from ipykernel.jsonutil import json_clean
1615
try:
1716
# available since ipyparallel 5.0.0
1817
from ipyparallel.serialize import serialize_object
@@ -46,7 +45,7 @@ def publish_data(self, data):
4645
buffer_threshold=session.buffer_threshold,
4746
item_threshold=session.item_threshold,
4847
)
49-
content = json_clean(dict(keys=list(data.keys())))
48+
content = dict(keys=list(data.keys()))
5049
session.send(self.pub_socket, 'data_message', content=content,
5150
parent=self.parent_header,
5251
buffers=buffers,
@@ -66,6 +65,6 @@ def publish_data(data):
6665
DeprecationWarning,
6766
stacklevel=2
6867
)
69-
68+
7069
from ipykernel.zmqshell import ZMQInteractiveShell
7170
ZMQInteractiveShell.instance().data_pub.publish_data(data)

ipykernel/debugger.py

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,18 @@
77
from tornado.queues import Queue
88
from tornado.locks import Event
99

10+
from IPython.core.getipython import get_ipython
11+
12+
from jupyter_client.jsonutil import date_default
13+
1014
from .compiler import (get_file_name, get_tmp_directory, get_tmp_hash_seed)
1115

12-
from IPython.core.getipython import get_ipython
1316

14-
from .jsonutil import json_clean
1517

1618
# Required for backwards compatiblity
1719
ROUTING_ID = getattr(zmq, 'ROUTING_ID', None) or zmq.IDENTITY
1820

21+
1922
class DebugpyMessageQueue:
2023

2124
HEADER = 'Content-Length: '
@@ -58,7 +61,7 @@ def put_tcp_frame(self, frame):
5861
self.header_pos = self.tcp_buffer.find(DebugpyMessageQueue.HEADER)
5962
if self.header_pos == -1:
6063
return
61-
64+
6265
self.log.debug('QUEUE - found header at pos %i', self.header_pos)
6366

6467
#Finds separator
@@ -94,7 +97,7 @@ def put_tcp_frame(self, frame):
9497

9598
async def get_message(self):
9699
return await self.message_queue.get()
97-
100+
98101

99102
class DebugpyClient:
100103

@@ -123,15 +126,20 @@ def _forward_event(self, msg):
123126
def _send_request(self, msg):
124127
if self.routing_id is None:
125128
self.routing_id = self.debugpy_stream.socket.getsockopt(ROUTING_ID)
126-
content = jsonapi.dumps(msg)
129+
content = jsonapi.dumps(
130+
msg,
131+
default=date_default,
132+
ensure_ascii=False,
133+
allow_nan=False,
134+
)
127135
content_length = str(len(content))
128136
buf = (DebugpyMessageQueue.HEADER + content_length + DebugpyMessageQueue.SEPARATOR).encode('ascii')
129137
buf += content
130138
self.log.debug("DEBUGPYCLIENT:")
131139
self.log.debug(self.routing_id)
132140
self.log.debug(buf)
133141
self.debugpy_stream.send_multipart((self.routing_id, buf))
134-
142+
135143
async def _wait_for_response(self):
136144
# Since events are never pushed to the message_queue
137145
# we can safely assume the next message in queue
@@ -141,7 +149,7 @@ async def _wait_for_response(self):
141149
async def _handle_init_sequence(self):
142150
# 1] Waits for initialized event
143151
await self.init_event.wait()
144-
152+
145153
# 2] Sends configurationDone request
146154
configurationDone = {
147155
'type': 'request',
@@ -193,6 +201,7 @@ async def send_dap_request(self, msg):
193201
self.log.debug(rep)
194202
return rep
195203

204+
196205
class Debugger:
197206

198207
# Requests that requires that the debugger has started
@@ -202,7 +211,7 @@ class Debugger:
202211
'variables', 'attach',
203212
'configurationDone'
204213
]
205-
214+
206215
# Requests that can be handled even if the debugger is not running
207216
static_debug_msg_types = [
208217
'debugInfo', 'inspectVariables', 'richInspectVariables'
@@ -215,7 +224,7 @@ def __init__(self, log, debugpy_stream, event_callback, shell_socket, session):
215224
self.session = session
216225
self.is_started = False
217226
self.event_callback = event_callback
218-
227+
219228
self.started_debug_handlers = {}
220229
for msg_type in Debugger.started_debug_msg_types:
221230
self.started_debug_handlers[msg_type] = getattr(self, msg_type)
@@ -264,7 +273,7 @@ def start(self):
264273
}
265274
self.session.send(self.shell_socket, 'execute_request', content,
266275
None, (self.shell_socket.getsockopt(ROUTING_ID)))
267-
276+
268277
ident, msg = self.session.recv(self.shell_socket, mode=0)
269278
self.debugpy_initialized = msg['content']['status'] == 'ok'
270279
self.debugpy_client.connect_tcp_socket()
@@ -424,8 +433,12 @@ async def inspectVariables(self, message):
424433
for k, v in get_ipython().user_ns.items():
425434
if self.accept_variable(k):
426435
try:
427-
val = json_clean(v)
428-
436+
val = jsonapi.dumps(
437+
v,
438+
default=date_default,
439+
ensure_ascii=False,
440+
allow_nan=False,
441+
)
429442
except ValueError:
430443
val = str(v)
431444
var_list.append({
@@ -486,7 +499,7 @@ async def richInspectVariables(self, message):
486499
'data': {},
487500
'metadata': {}
488501
}
489-
502+
490503
for key, value in repr_data.items():
491504
body['data']['key'] = value
492505
if repr_metadata.has_key(key):

ipykernel/displayhook.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import sys
88

99
from IPython.core.displayhook import DisplayHook
10-
from ipykernel.jsonutil import encode_images, json_clean
1110
from traitlets import Instance, Dict, Any
1211
from jupyter_client.session import extract_header, Session
1312

@@ -68,7 +67,7 @@ def write_output_prompt(self):
6867
self.msg['content']['execution_count'] = self.prompt_count
6968

7069
def write_format_data(self, format_dict, md_dict=None):
71-
self.msg['content']['data'] = json_clean(encode_images(format_dict))
70+
self.msg['content']['data'] = format_dict
7271
self.msg['content']['metadata'] = md_dict
7372

7473
def finish_displayhook(self):

ipykernel/inprocess/ipkernel.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import sys
99

1010
from IPython.core.interactiveshell import InteractiveShellABC
11-
from ipykernel.jsonutil import json_clean
1211
from traitlets import Any, Enum, Instance, List, Type, default
1312
from ipykernel.ipkernel import IPythonKernel
1413
from ipykernel.zmqshell import ZMQInteractiveShell
@@ -98,7 +97,7 @@ def _input_request(self, prompt, ident, parent, password=False):
9897
sys.stdout.flush()
9998

10099
# Send the input request.
101-
content = json_clean(dict(prompt=prompt, password=password))
100+
content = dict(prompt=prompt, password=password)
102101
msg = self.session.msg('input_request', content, parent)
103102
for frontend in self.frontends:
104103
if frontend.session.session == parent['header']['session']:

ipykernel/jsonutil.py

Lines changed: 5 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
# front of PDF base64-encoded
4343
PDF64 = b'JVBER'
4444

45+
4546
def encode_images(format_dict):
4647
"""b64-encodes images in a displaypub format dict
4748
@@ -68,7 +69,9 @@ def encode_images(format_dict):
6869

6970

7071
def json_clean(obj):
71-
"""Clean an object to ensure it's safe to encode in JSON.
72+
"""Deprecated, this is a no-op now.
73+
74+
Clean an object to ensure it's safe to encode in JSON.
7275
7376
Atomic, immutable objects are returned unmodified. Sets and tuples are
7477
converted to lists, lists are copied and dicts are also copied.
@@ -89,59 +92,4 @@ def json_clean(obj):
8992
it simply sanitizes it so that there will be no encoding errors later.
9093
9194
"""
92-
# types that are 'atomic' and ok in json as-is.
93-
atomic_ok = (str, type(None))
94-
95-
# containers that we need to convert into lists
96-
container_to_list = (tuple, set, types.GeneratorType)
97-
98-
# Since bools are a subtype of Integrals, which are a subtype of Reals,
99-
# we have to check them in that order.
100-
101-
if isinstance(obj, bool):
102-
return obj
103-
104-
if isinstance(obj, numbers.Integral):
105-
# cast int to int, in case subclasses override __str__ (e.g. boost enum, #4598)
106-
return int(obj)
107-
108-
if isinstance(obj, numbers.Real):
109-
# cast out-of-range floats to their reprs
110-
if math.isnan(obj) or math.isinf(obj):
111-
return repr(obj)
112-
return float(obj)
113-
114-
if isinstance(obj, atomic_ok):
115-
return obj
116-
117-
if isinstance(obj, bytes):
118-
# unanmbiguous binary data is base64-encoded
119-
# (this probably should have happened upstream)
120-
return b2a_base64(obj).decode('ascii')
121-
122-
if isinstance(obj, container_to_list) or (
123-
hasattr(obj, '__iter__') and hasattr(obj, next_attr_name)):
124-
obj = list(obj)
125-
126-
if isinstance(obj, list):
127-
return [json_clean(x) for x in obj]
128-
129-
if isinstance(obj, dict):
130-
# First, validate that the dict won't lose data in conversion due to
131-
# key collisions after stringification. This can happen with keys like
132-
# True and 'true' or 1 and '1', which collide in JSON.
133-
nkeys = len(obj)
134-
nkeys_collapsed = len(set(map(str, obj)))
135-
if nkeys != nkeys_collapsed:
136-
raise ValueError('dict cannot be safely converted to JSON: '
137-
'key collision would lead to dropped values')
138-
# If all OK, proceed by making the new dict that will be json-safe
139-
out = {}
140-
for k,v in obj.items():
141-
out[str(k)] = json_clean(v)
142-
return out
143-
if isinstance(obj, datetime):
144-
return obj.strftime(ISO8601)
145-
146-
# we don't understand it, it's probably an unserializable object
147-
raise ValueError("Can't clean for JSON: %r" % obj)
95+
return obj

ipykernel/kernelbase.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131

3232
from traitlets.config.configurable import SingletonConfigurable
3333
from IPython.core.error import StdinNotImplementedError
34-
from ipykernel.jsonutil import json_clean
3534
from traitlets import (
3635
Any, Instance, Float, Dict, List, Set, Integer, Unicode, Bool,
3736
observe, default
@@ -657,7 +656,6 @@ async def execute_request(self, stream, ident, parent):
657656
time.sleep(self._execute_sleep)
658657

659658
# Send the reply.
660-
reply_content = json_clean(reply_content)
661659
metadata = self.finish_metadata(parent, metadata, reply_content)
662660

663661
reply_msg = self.session.send(stream, 'execute_reply',
@@ -684,7 +682,6 @@ async def complete_request(self, stream, ident, parent):
684682
if inspect.isawaitable(matches):
685683
matches = await matches
686684

687-
matches = json_clean(matches)
688685
self.session.send(stream, "complete_reply", matches, parent, ident)
689686

690687
def do_complete(self, code, cursor_pos):
@@ -707,7 +704,6 @@ async def inspect_request(self, stream, ident, parent):
707704
reply_content = await reply_content
708705

709706
# Before we send this object over, we scrub it for JSON usage
710-
reply_content = json_clean(reply_content)
711707
msg = self.session.send(stream, 'inspect_reply',
712708
reply_content, parent, ident)
713709
self.log.debug("%s", msg)
@@ -724,7 +720,6 @@ async def history_request(self, stream, ident, parent):
724720
if inspect.isawaitable(reply_content):
725721
reply_content = await reply_content
726722

727-
reply_content = json_clean(reply_content)
728723
msg = self.session.send(stream, 'history_reply',
729724
reply_content, parent, ident)
730725
self.log.debug("%s", msg)
@@ -838,7 +833,6 @@ async def is_complete_request(self, stream, ident, parent):
838833
reply_content = self.do_is_complete(code)
839834
if inspect.isawaitable(reply_content):
840835
reply_content = await reply_content
841-
reply_content = json_clean(reply_content)
842836
reply_msg = self.session.send(stream, 'is_complete_reply',
843837
reply_content, parent, ident)
844838
self.log.debug("%s", reply_msg)
@@ -854,7 +848,6 @@ async def debug_request(self, stream, ident, parent):
854848
reply_content = self.do_debug_request(content)
855849
if inspect.isawaitable(reply_content):
856850
reply_content = await reply_content
857-
reply_content = json_clean(reply_content)
858851
reply_msg = self.session.send(stream, 'debug_reply', reply_content,
859852
parent, ident)
860853
self.log.debug("%s", reply_msg)
@@ -1026,7 +1019,7 @@ def _input_request(self, prompt, ident, parent, password=False):
10261019
raise
10271020

10281021
# Send the input request.
1029-
content = json_clean(dict(prompt=prompt, password=password))
1022+
content = dict(prompt=prompt, password=password)
10301023
self.session.send(self.stdin_socket, 'input_request', content, parent,
10311024
ident=ident)
10321025

0 commit comments

Comments
 (0)