##// END OF EJS Templates
move client code from IPython.kernel to jupyter_client
Min RK -
Show More
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
1 NO CONTENT: file renamed from IPython/kernel/__init__.py to jupyter_client/__init__.py
NO CONTENT: file renamed from IPython/kernel/__init__.py to jupyter_client/__init__.py
@@ -12,7 +12,7 b' from IPython.utils.tokenutil import token_at_cursor'
12 def code_to_line(code, cursor_pos):
12 def code_to_line(code, cursor_pos):
13 """Turn a multiline code block and cursor position into a single line
13 """Turn a multiline code block and cursor position into a single line
14 and new cursor position.
14 and new cursor position.
15
15
16 For adapting ``complete_`` and ``object_info_request``.
16 For adapting ``complete_`` and ``object_info_request``.
17 """
17 """
18 if not code:
18 if not code:
@@ -28,42 +28,42 b' def code_to_line(code, cursor_pos):'
28
28
29 class Adapter(object):
29 class Adapter(object):
30 """Base class for adapting messages
30 """Base class for adapting messages
31
31
32 Override message_type(msg) methods to create adapters.
32 Override message_type(msg) methods to create adapters.
33 """
33 """
34
34
35 msg_type_map = {}
35 msg_type_map = {}
36
36
37 def update_header(self, msg):
37 def update_header(self, msg):
38 return msg
38 return msg
39
39
40 def update_metadata(self, msg):
40 def update_metadata(self, msg):
41 return msg
41 return msg
42
42
43 def update_msg_type(self, msg):
43 def update_msg_type(self, msg):
44 header = msg['header']
44 header = msg['header']
45 msg_type = header['msg_type']
45 msg_type = header['msg_type']
46 if msg_type in self.msg_type_map:
46 if msg_type in self.msg_type_map:
47 msg['msg_type'] = header['msg_type'] = self.msg_type_map[msg_type]
47 msg['msg_type'] = header['msg_type'] = self.msg_type_map[msg_type]
48 return msg
48 return msg
49
49
50 def handle_reply_status_error(self, msg):
50 def handle_reply_status_error(self, msg):
51 """This will be called *instead of* the regular handler
51 """This will be called *instead of* the regular handler
52
52
53 on any reply with status != ok
53 on any reply with status != ok
54 """
54 """
55 return msg
55 return msg
56
56
57 def __call__(self, msg):
57 def __call__(self, msg):
58 msg = self.update_header(msg)
58 msg = self.update_header(msg)
59 msg = self.update_metadata(msg)
59 msg = self.update_metadata(msg)
60 msg = self.update_msg_type(msg)
60 msg = self.update_msg_type(msg)
61 header = msg['header']
61 header = msg['header']
62
62
63 handler = getattr(self, header['msg_type'], None)
63 handler = getattr(self, header['msg_type'], None)
64 if handler is None:
64 if handler is None:
65 return msg
65 return msg
66
66
67 # handle status=error replies separately (no change, at present)
67 # handle status=error replies separately (no change, at present)
68 if msg['content'].get('status', None) in {'error', 'aborted'}:
68 if msg['content'].get('status', None) in {'error', 'aborted'}:
69 return self.handle_reply_status_error(msg)
69 return self.handle_reply_status_error(msg)
@@ -71,7 +71,7 b' class Adapter(object):'
71
71
72 def _version_str_to_list(version):
72 def _version_str_to_list(version):
73 """convert a version string to a list of ints
73 """convert a version string to a list of ints
74
74
75 non-int segments are excluded
75 non-int segments are excluded
76 """
76 """
77 v = []
77 v = []
@@ -84,9 +84,9 b' def _version_str_to_list(version):'
84
84
85 class V5toV4(Adapter):
85 class V5toV4(Adapter):
86 """Adapt msg protocol v5 to v4"""
86 """Adapt msg protocol v5 to v4"""
87
87
88 version = '4.1'
88 version = '4.1'
89
89
90 msg_type_map = {
90 msg_type_map = {
91 'execute_result' : 'pyout',
91 'execute_result' : 'pyout',
92 'execute_input' : 'pyin',
92 'execute_input' : 'pyin',
@@ -94,13 +94,13 b' class V5toV4(Adapter):'
94 'inspect_request' : 'object_info_request',
94 'inspect_request' : 'object_info_request',
95 'inspect_reply' : 'object_info_reply',
95 'inspect_reply' : 'object_info_reply',
96 }
96 }
97
97
98 def update_header(self, msg):
98 def update_header(self, msg):
99 msg['header'].pop('version', None)
99 msg['header'].pop('version', None)
100 return msg
100 return msg
101
101
102 # shell channel
102 # shell channel
103
103
104 def kernel_info_reply(self, msg):
104 def kernel_info_reply(self, msg):
105 v4c = {}
105 v4c = {}
106 content = msg['content']
106 content = msg['content']
@@ -117,31 +117,31 b' class V5toV4(Adapter):'
117 v4c.setdefault('language_version', _version_str_to_list(language_info['version']))
117 v4c.setdefault('language_version', _version_str_to_list(language_info['version']))
118 msg['content'] = v4c
118 msg['content'] = v4c
119 return msg
119 return msg
120
120
121 def execute_request(self, msg):
121 def execute_request(self, msg):
122 content = msg['content']
122 content = msg['content']
123 content.setdefault('user_variables', [])
123 content.setdefault('user_variables', [])
124 return msg
124 return msg
125
125
126 def execute_reply(self, msg):
126 def execute_reply(self, msg):
127 content = msg['content']
127 content = msg['content']
128 content.setdefault('user_variables', {})
128 content.setdefault('user_variables', {})
129 # TODO: handle payloads
129 # TODO: handle payloads
130 return msg
130 return msg
131
131
132 def complete_request(self, msg):
132 def complete_request(self, msg):
133 content = msg['content']
133 content = msg['content']
134 code = content['code']
134 code = content['code']
135 cursor_pos = content['cursor_pos']
135 cursor_pos = content['cursor_pos']
136 line, cursor_pos = code_to_line(code, cursor_pos)
136 line, cursor_pos = code_to_line(code, cursor_pos)
137
137
138 new_content = msg['content'] = {}
138 new_content = msg['content'] = {}
139 new_content['text'] = ''
139 new_content['text'] = ''
140 new_content['line'] = line
140 new_content['line'] = line
141 new_content['block'] = None
141 new_content['block'] = None
142 new_content['cursor_pos'] = cursor_pos
142 new_content['cursor_pos'] = cursor_pos
143 return msg
143 return msg
144
144
145 def complete_reply(self, msg):
145 def complete_reply(self, msg):
146 content = msg['content']
146 content = msg['content']
147 cursor_start = content.pop('cursor_start')
147 cursor_start = content.pop('cursor_start')
@@ -150,25 +150,25 b' class V5toV4(Adapter):'
150 content['matched_text'] = content['matches'][0][:match_len]
150 content['matched_text'] = content['matches'][0][:match_len]
151 content.pop('metadata', None)
151 content.pop('metadata', None)
152 return msg
152 return msg
153
153
154 def object_info_request(self, msg):
154 def object_info_request(self, msg):
155 content = msg['content']
155 content = msg['content']
156 code = content['code']
156 code = content['code']
157 cursor_pos = content['cursor_pos']
157 cursor_pos = content['cursor_pos']
158 line, _ = code_to_line(code, cursor_pos)
158 line, _ = code_to_line(code, cursor_pos)
159
159
160 new_content = msg['content'] = {}
160 new_content = msg['content'] = {}
161 new_content['oname'] = token_at_cursor(code, cursor_pos)
161 new_content['oname'] = token_at_cursor(code, cursor_pos)
162 new_content['detail_level'] = content['detail_level']
162 new_content['detail_level'] = content['detail_level']
163 return msg
163 return msg
164
164
165 def object_info_reply(self, msg):
165 def object_info_reply(self, msg):
166 """inspect_reply can't be easily backward compatible"""
166 """inspect_reply can't be easily backward compatible"""
167 msg['content'] = {'found' : False, 'oname' : 'unknown'}
167 msg['content'] = {'found' : False, 'oname' : 'unknown'}
168 return msg
168 return msg
169
169
170 # iopub channel
170 # iopub channel
171
171
172 def stream(self, msg):
172 def stream(self, msg):
173 content = msg['content']
173 content = msg['content']
174 content['data'] = content.pop('text')
174 content['data'] = content.pop('text')
@@ -185,9 +185,9 b' class V5toV4(Adapter):'
185 # warn?
185 # warn?
186 pass
186 pass
187 return msg
187 return msg
188
188
189 # stdin channel
189 # stdin channel
190
190
191 def input_request(self, msg):
191 def input_request(self, msg):
192 msg['content'].pop('password', None)
192 msg['content'].pop('password', None)
193 return msg
193 return msg
@@ -196,38 +196,38 b' class V5toV4(Adapter):'
196 class V4toV5(Adapter):
196 class V4toV5(Adapter):
197 """Convert msg spec V4 to V5"""
197 """Convert msg spec V4 to V5"""
198 version = '5.0'
198 version = '5.0'
199
199
200 # invert message renames above
200 # invert message renames above
201 msg_type_map = {v:k for k,v in V5toV4.msg_type_map.items()}
201 msg_type_map = {v:k for k,v in V5toV4.msg_type_map.items()}
202
202
203 def update_header(self, msg):
203 def update_header(self, msg):
204 msg['header']['version'] = self.version
204 msg['header']['version'] = self.version
205 return msg
205 return msg
206
206
207 # shell channel
207 # shell channel
208
208
209 def kernel_info_reply(self, msg):
209 def kernel_info_reply(self, msg):
210 content = msg['content']
210 content = msg['content']
211 for key in ('protocol_version', 'ipython_version'):
211 for key in ('protocol_version', 'ipython_version'):
212 if key in content:
212 if key in content:
213 content[key] = '.'.join(map(str, content[key]))
213 content[key] = '.'.join(map(str, content[key]))
214
214
215 content.setdefault('protocol_version', '4.1')
215 content.setdefault('protocol_version', '4.1')
216
216
217 if content['language'].startswith('python') and 'ipython_version' in content:
217 if content['language'].startswith('python') and 'ipython_version' in content:
218 content['implementation'] = 'ipython'
218 content['implementation'] = 'ipython'
219 content['implementation_version'] = content.pop('ipython_version')
219 content['implementation_version'] = content.pop('ipython_version')
220
220
221 language = content.pop('language')
221 language = content.pop('language')
222 language_info = content.setdefault('language_info', {})
222 language_info = content.setdefault('language_info', {})
223 language_info.setdefault('name', language)
223 language_info.setdefault('name', language)
224 if 'language_version' in content:
224 if 'language_version' in content:
225 language_version = '.'.join(map(str, content.pop('language_version')))
225 language_version = '.'.join(map(str, content.pop('language_version')))
226 language_info.setdefault('version', language_version)
226 language_info.setdefault('version', language_version)
227
227
228 content['banner'] = ''
228 content['banner'] = ''
229 return msg
229 return msg
230
230
231 def execute_request(self, msg):
231 def execute_request(self, msg):
232 content = msg['content']
232 content = msg['content']
233 user_variables = content.pop('user_variables', [])
233 user_variables = content.pop('user_variables', [])
@@ -235,7 +235,7 b' class V4toV5(Adapter):'
235 for v in user_variables:
235 for v in user_variables:
236 user_expressions[v] = v
236 user_expressions[v] = v
237 return msg
237 return msg
238
238
239 def execute_reply(self, msg):
239 def execute_reply(self, msg):
240 content = msg['content']
240 content = msg['content']
241 user_expressions = content.setdefault('user_expressions', {})
241 user_expressions = content.setdefault('user_expressions', {})
@@ -251,15 +251,15 b' class V4toV5(Adapter):'
251 payload['data']['text/plain'] = payload.pop('text')
251 payload['data']['text/plain'] = payload.pop('text')
252
252
253 return msg
253 return msg
254
254
255 def complete_request(self, msg):
255 def complete_request(self, msg):
256 old_content = msg['content']
256 old_content = msg['content']
257
257
258 new_content = msg['content'] = {}
258 new_content = msg['content'] = {}
259 new_content['code'] = old_content['line']
259 new_content['code'] = old_content['line']
260 new_content['cursor_pos'] = old_content['cursor_pos']
260 new_content['cursor_pos'] = old_content['cursor_pos']
261 return msg
261 return msg
262
262
263 def complete_reply(self, msg):
263 def complete_reply(self, msg):
264 # complete_reply needs more context than we have to get cursor_start and end.
264 # complete_reply needs more context than we have to get cursor_start and end.
265 # use special end=null to indicate current cursor position and negative offset
265 # use special end=null to indicate current cursor position and negative offset
@@ -276,17 +276,17 b' class V4toV5(Adapter):'
276 new_content['cursor_end'] = None
276 new_content['cursor_end'] = None
277 new_content['metadata'] = {}
277 new_content['metadata'] = {}
278 return msg
278 return msg
279
279
280 def inspect_request(self, msg):
280 def inspect_request(self, msg):
281 content = msg['content']
281 content = msg['content']
282 name = content['oname']
282 name = content['oname']
283
283
284 new_content = msg['content'] = {}
284 new_content = msg['content'] = {}
285 new_content['code'] = name
285 new_content['code'] = name
286 new_content['cursor_pos'] = len(name)
286 new_content['cursor_pos'] = len(name)
287 new_content['detail_level'] = content['detail_level']
287 new_content['detail_level'] = content['detail_level']
288 return msg
288 return msg
289
289
290 def inspect_reply(self, msg):
290 def inspect_reply(self, msg):
291 """inspect_reply can't be easily backward compatible"""
291 """inspect_reply can't be easily backward compatible"""
292 content = msg['content']
292 content = msg['content']
@@ -309,9 +309,9 b' class V4toV5(Adapter):'
309 lines.append("<empty docstring>")
309 lines.append("<empty docstring>")
310 data['text/plain'] = '\n'.join(lines)
310 data['text/plain'] = '\n'.join(lines)
311 return msg
311 return msg
312
312
313 # iopub channel
313 # iopub channel
314
314
315 def stream(self, msg):
315 def stream(self, msg):
316 content = msg['content']
316 content = msg['content']
317 content['text'] = content.pop('data')
317 content['text'] = content.pop('data')
@@ -328,30 +328,30 b' class V4toV5(Adapter):'
328 # warn?
328 # warn?
329 pass
329 pass
330 return msg
330 return msg
331
331
332 # stdin channel
332 # stdin channel
333
333
334 def input_request(self, msg):
334 def input_request(self, msg):
335 msg['content'].setdefault('password', False)
335 msg['content'].setdefault('password', False)
336 return msg
336 return msg
337
337
338
338
339
339
340 def adapt(msg, to_version=kernel_protocol_version_info[0]):
340 def adapt(msg, to_version=kernel_protocol_version_info[0]):
341 """Adapt a single message to a target version
341 """Adapt a single message to a target version
342
342
343 Parameters
343 Parameters
344 ----------
344 ----------
345
345
346 msg : dict
346 msg : dict
347 An IPython message.
347 An IPython message.
348 to_version : int, optional
348 to_version : int, optional
349 The target major version.
349 The target major version.
350 If unspecified, adapt to the current version for IPython.
350 If unspecified, adapt to the current version for IPython.
351
351
352 Returns
352 Returns
353 -------
353 -------
354
354
355 msg : dict
355 msg : dict
356 An IPython message appropriate in the new version.
356 An IPython message appropriate in the new version.
357 """
357 """
1 NO CONTENT: file renamed from IPython/kernel/blocking/__init__.py to jupyter_client/blocking/__init__.py
NO CONTENT: file renamed from IPython/kernel/blocking/__init__.py to jupyter_client/blocking/__init__.py
@@ -89,4 +89,3 b' class ZMQSocketChannel(object):'
89
89
90 def start(self):
90 def start(self):
91 pass
91 pass
92
1 NO CONTENT: file renamed from IPython/kernel/blocking/client.py to jupyter_client/blocking/client.py
NO CONTENT: file renamed from IPython/kernel/blocking/client.py to jupyter_client/blocking/client.py
1 NO CONTENT: file renamed from IPython/kernel/channels.py to jupyter_client/channels.py
NO CONTENT: file renamed from IPython/kernel/channels.py to jupyter_client/channels.py
1 NO CONTENT: file renamed from IPython/kernel/channelsabc.py to jupyter_client/channelsabc.py
NO CONTENT: file renamed from IPython/kernel/channelsabc.py to jupyter_client/channelsabc.py
1 NO CONTENT: file renamed from IPython/kernel/client.py to jupyter_client/client.py
NO CONTENT: file renamed from IPython/kernel/client.py to jupyter_client/client.py
1 NO CONTENT: file renamed from IPython/kernel/clientabc.py to jupyter_client/clientabc.py
NO CONTENT: file renamed from IPython/kernel/clientabc.py to jupyter_client/clientabc.py
@@ -44,7 +44,7 b' def write_connection_file(fname=None, shell_port=0, iopub_port=0, stdin_port=0, '
44 signature_scheme='hmac-sha256',
44 signature_scheme='hmac-sha256',
45 ):
45 ):
46 """Generates a JSON config file, including the selection of random ports.
46 """Generates a JSON config file, including the selection of random ports.
47
47
48 Parameters
48 Parameters
49 ----------
49 ----------
50
50
@@ -71,7 +71,7 b' def write_connection_file(fname=None, shell_port=0, iopub_port=0, stdin_port=0, '
71
71
72 key : str, optional
72 key : str, optional
73 The Session key used for message authentication.
73 The Session key used for message authentication.
74
74
75 signature_scheme : str, optional
75 signature_scheme : str, optional
76 The scheme used for message authentication.
76 The scheme used for message authentication.
77 This has the form 'digest-hash', where 'digest'
77 This has the form 'digest-hash', where 'digest'
@@ -87,9 +87,9 b' def write_connection_file(fname=None, shell_port=0, iopub_port=0, stdin_port=0, '
87 if not fname:
87 if not fname:
88 fd, fname = tempfile.mkstemp('.json')
88 fd, fname = tempfile.mkstemp('.json')
89 os.close(fd)
89 os.close(fd)
90
90
91 # Find open ports as necessary.
91 # Find open ports as necessary.
92
92
93 ports = []
93 ports = []
94 ports_needed = int(shell_port <= 0) + \
94 ports_needed = int(shell_port <= 0) + \
95 int(iopub_port <= 0) + \
95 int(iopub_port <= 0) + \
@@ -124,7 +124,7 b' def write_connection_file(fname=None, shell_port=0, iopub_port=0, stdin_port=0, '
124 control_port = ports.pop(0)
124 control_port = ports.pop(0)
125 if hb_port <= 0:
125 if hb_port <= 0:
126 hb_port = ports.pop(0)
126 hb_port = ports.pop(0)
127
127
128 cfg = dict( shell_port=shell_port,
128 cfg = dict( shell_port=shell_port,
129 iopub_port=iopub_port,
129 iopub_port=iopub_port,
130 stdin_port=stdin_port,
130 stdin_port=stdin_port,
@@ -135,16 +135,16 b' def write_connection_file(fname=None, shell_port=0, iopub_port=0, stdin_port=0, '
135 cfg['key'] = bytes_to_str(key)
135 cfg['key'] = bytes_to_str(key)
136 cfg['transport'] = transport
136 cfg['transport'] = transport
137 cfg['signature_scheme'] = signature_scheme
137 cfg['signature_scheme'] = signature_scheme
138
138
139 with open(fname, 'w') as f:
139 with open(fname, 'w') as f:
140 f.write(json.dumps(cfg, indent=2))
140 f.write(json.dumps(cfg, indent=2))
141
141
142 return fname, cfg
142 return fname, cfg
143
143
144
144
145 def get_connection_file(app=None):
145 def get_connection_file(app=None):
146 """Return the path to the connection file of an app
146 """Return the path to the connection file of an app
147
147
148 Parameters
148 Parameters
149 ----------
149 ----------
150 app : IPKernelApp instance [optional]
150 app : IPKernelApp instance [optional]
@@ -161,18 +161,18 b' def get_connection_file(app=None):'
161
161
162 def find_connection_file(filename='kernel-*.json', profile=None):
162 def find_connection_file(filename='kernel-*.json', profile=None):
163 """find a connection file, and return its absolute path.
163 """find a connection file, and return its absolute path.
164
164
165 The current working directory and the profile's security
165 The current working directory and the profile's security
166 directory will be searched for the file if it is not given by
166 directory will be searched for the file if it is not given by
167 absolute path.
167 absolute path.
168
168
169 If profile is unspecified, then the current running application's
169 If profile is unspecified, then the current running application's
170 profile will be used, or 'default', if not run from IPython.
170 profile will be used, or 'default', if not run from IPython.
171
171
172 If the argument does not match an existing file, it will be interpreted as a
172 If the argument does not match an existing file, it will be interpreted as a
173 fileglob, and the matching file in the profile's security dir with
173 fileglob, and the matching file in the profile's security dir with
174 the latest access time will be used.
174 the latest access time will be used.
175
175
176 Parameters
176 Parameters
177 ----------
177 ----------
178 filename : str
178 filename : str
@@ -180,7 +180,7 b" def find_connection_file(filename='kernel-*.json', profile=None):"
180 profile : str [optional]
180 profile : str [optional]
181 The name of the profile to use when searching for the connection file,
181 The name of the profile to use when searching for the connection file,
182 if different from the current IPython session or 'default'.
182 if different from the current IPython session or 'default'.
183
183
184 Returns
184 Returns
185 -------
185 -------
186 str : The absolute path of the connection file.
186 str : The absolute path of the connection file.
@@ -191,7 +191,7 b" def find_connection_file(filename='kernel-*.json', profile=None):"
191 return filefind(filename)
191 return filefind(filename)
192 except IOError:
192 except IOError:
193 pass
193 pass
194
194
195 if profile is None:
195 if profile is None:
196 # profile unspecified, check if running from an IPython app
196 # profile unspecified, check if running from an IPython app
197 if IPApp.initialized():
197 if IPApp.initialized():
@@ -204,15 +204,15 b" def find_connection_file(filename='kernel-*.json', profile=None):"
204 # find profiledir by profile name:
204 # find profiledir by profile name:
205 profile_dir = ProfileDir.find_profile_dir_by_name(get_ipython_dir(), profile)
205 profile_dir = ProfileDir.find_profile_dir_by_name(get_ipython_dir(), profile)
206 security_dir = profile_dir.security_dir
206 security_dir = profile_dir.security_dir
207
207
208 try:
208 try:
209 # first, try explicit name
209 # first, try explicit name
210 return filefind(filename, ['.', security_dir])
210 return filefind(filename, ['.', security_dir])
211 except IOError:
211 except IOError:
212 pass
212 pass
213
213
214 # not found by full name
214 # not found by full name
215
215
216 if '*' in filename:
216 if '*' in filename:
217 # given as a glob already
217 # given as a glob already
218 pat = filename
218 pat = filename
@@ -231,14 +231,14 b" def find_connection_file(filename='kernel-*.json', profile=None):"
231
231
232 def get_connection_info(connection_file=None, unpack=False, profile=None):
232 def get_connection_info(connection_file=None, unpack=False, profile=None):
233 """Return the connection information for the current Kernel.
233 """Return the connection information for the current Kernel.
234
234
235 Parameters
235 Parameters
236 ----------
236 ----------
237 connection_file : str [optional]
237 connection_file : str [optional]
238 The connection file to be used. Can be given by absolute path, or
238 The connection file to be used. Can be given by absolute path, or
239 IPython will search in the security directory of a given profile.
239 IPython will search in the security directory of a given profile.
240 If run from IPython,
240 If run from IPython,
241
241
242 If unspecified, the connection file for the currently running
242 If unspecified, the connection file for the currently running
243 IPython Kernel will be used, which is only allowed from inside a kernel.
243 IPython Kernel will be used, which is only allowed from inside a kernel.
244 unpack : bool [default: False]
244 unpack : bool [default: False]
@@ -247,8 +247,8 b' def get_connection_info(connection_file=None, unpack=False, profile=None):'
247 profile : str [optional]
247 profile : str [optional]
248 The name of the profile to use when searching for the connection file,
248 The name of the profile to use when searching for the connection file,
249 if different from the current IPython session or 'default'.
249 if different from the current IPython session or 'default'.
250
250
251
251
252 Returns
252 Returns
253 -------
253 -------
254 The connection dictionary of the current kernel, as string or dict,
254 The connection dictionary of the current kernel, as string or dict,
@@ -260,10 +260,10 b' def get_connection_info(connection_file=None, unpack=False, profile=None):'
260 else:
260 else:
261 # connection file specified, allow shortnames:
261 # connection file specified, allow shortnames:
262 cf = find_connection_file(connection_file, profile=profile)
262 cf = find_connection_file(connection_file, profile=profile)
263
263
264 with open(cf) as f:
264 with open(cf) as f:
265 info = f.read()
265 info = f.read()
266
266
267 if unpack:
267 if unpack:
268 info = json.loads(info)
268 info = json.loads(info)
269 # ensure key is bytes:
269 # ensure key is bytes:
@@ -273,17 +273,17 b' def get_connection_info(connection_file=None, unpack=False, profile=None):'
273
273
274 def connect_qtconsole(connection_file=None, argv=None, profile=None):
274 def connect_qtconsole(connection_file=None, argv=None, profile=None):
275 """Connect a qtconsole to the current kernel.
275 """Connect a qtconsole to the current kernel.
276
276
277 This is useful for connecting a second qtconsole to a kernel, or to a
277 This is useful for connecting a second qtconsole to a kernel, or to a
278 local notebook.
278 local notebook.
279
279
280 Parameters
280 Parameters
281 ----------
281 ----------
282 connection_file : str [optional]
282 connection_file : str [optional]
283 The connection file to be used. Can be given by absolute path, or
283 The connection file to be used. Can be given by absolute path, or
284 IPython will search in the security directory of a given profile.
284 IPython will search in the security directory of a given profile.
285 If run from IPython,
285 If run from IPython,
286
286
287 If unspecified, the connection file for the currently running
287 If unspecified, the connection file for the currently running
288 IPython Kernel will be used, which is only allowed from inside a kernel.
288 IPython Kernel will be used, which is only allowed from inside a kernel.
289 argv : list [optional]
289 argv : list [optional]
@@ -291,25 +291,25 b' def connect_qtconsole(connection_file=None, argv=None, profile=None):'
291 profile : str [optional]
291 profile : str [optional]
292 The name of the profile to use when searching for the connection file,
292 The name of the profile to use when searching for the connection file,
293 if different from the current IPython session or 'default'.
293 if different from the current IPython session or 'default'.
294
294
295
295
296 Returns
296 Returns
297 -------
297 -------
298 :class:`subprocess.Popen` instance running the qtconsole frontend
298 :class:`subprocess.Popen` instance running the qtconsole frontend
299 """
299 """
300 argv = [] if argv is None else argv
300 argv = [] if argv is None else argv
301
301
302 if connection_file is None:
302 if connection_file is None:
303 # get connection file from current kernel
303 # get connection file from current kernel
304 cf = get_connection_file()
304 cf = get_connection_file()
305 else:
305 else:
306 cf = find_connection_file(connection_file, profile=profile)
306 cf = find_connection_file(connection_file, profile=profile)
307
307
308 cmd = ';'.join([
308 cmd = ';'.join([
309 "from IPython.qt.console import qtconsoleapp",
309 "from IPython.qt.console import qtconsoleapp",
310 "qtconsoleapp.main()"
310 "qtconsoleapp.main()"
311 ])
311 ])
312
312
313 return Popen([sys.executable, '-c', cmd, '--existing', cf] + argv,
313 return Popen([sys.executable, '-c', cmd, '--existing', cf] + argv,
314 stdout=PIPE, stderr=PIPE, close_fds=(sys.platform != 'win32'),
314 stdout=PIPE, stderr=PIPE, close_fds=(sys.platform != 'win32'),
315 )
315 )
@@ -317,12 +317,12 b' def connect_qtconsole(connection_file=None, argv=None, profile=None):'
317
317
318 def tunnel_to_kernel(connection_info, sshserver, sshkey=None):
318 def tunnel_to_kernel(connection_info, sshserver, sshkey=None):
319 """tunnel connections to a kernel via ssh
319 """tunnel connections to a kernel via ssh
320
320
321 This will open four SSH tunnels from localhost on this machine to the
321 This will open four SSH tunnels from localhost on this machine to the
322 ports associated with the kernel. They can be either direct
322 ports associated with the kernel. They can be either direct
323 localhost-localhost tunnels, or if an intermediate server is necessary,
323 localhost-localhost tunnels, or if an intermediate server is necessary,
324 the kernel must be listening on a public IP.
324 the kernel must be listening on a public IP.
325
325
326 Parameters
326 Parameters
327 ----------
327 ----------
328 connection_info : dict or str (path)
328 connection_info : dict or str (path)
@@ -334,10 +334,10 b' def tunnel_to_kernel(connection_info, sshserver, sshkey=None):'
334 Path to file containing ssh key to use for authentication.
334 Path to file containing ssh key to use for authentication.
335 Only necessary if your ssh config does not already associate
335 Only necessary if your ssh config does not already associate
336 a keyfile with the host.
336 a keyfile with the host.
337
337
338 Returns
338 Returns
339 -------
339 -------
340
340
341 (shell, iopub, stdin, hb) : ints
341 (shell, iopub, stdin, hb) : ints
342 The four ports on localhost that have been forwarded to the kernel.
342 The four ports on localhost that have been forwarded to the kernel.
343 """
343 """
@@ -346,22 +346,22 b' def tunnel_to_kernel(connection_info, sshserver, sshkey=None):'
346 # it's a path, unpack it
346 # it's a path, unpack it
347 with open(connection_info) as f:
347 with open(connection_info) as f:
348 connection_info = json.loads(f.read())
348 connection_info = json.loads(f.read())
349
349
350 cf = connection_info
350 cf = connection_info
351
351
352 lports = tunnel.select_random_ports(4)
352 lports = tunnel.select_random_ports(4)
353 rports = cf['shell_port'], cf['iopub_port'], cf['stdin_port'], cf['hb_port']
353 rports = cf['shell_port'], cf['iopub_port'], cf['stdin_port'], cf['hb_port']
354
354
355 remote_ip = cf['ip']
355 remote_ip = cf['ip']
356
356
357 if tunnel.try_passwordless_ssh(sshserver, sshkey):
357 if tunnel.try_passwordless_ssh(sshserver, sshkey):
358 password=False
358 password=False
359 else:
359 else:
360 password = getpass("SSH Password for %s: " % cast_bytes_py2(sshserver))
360 password = getpass("SSH Password for %s: " % cast_bytes_py2(sshserver))
361
361
362 for lp,rp in zip(lports, rports):
362 for lp,rp in zip(lports, rports):
363 tunnel.ssh_tunnel(lp, rp, sshserver, remote_ip, sshkey, password)
363 tunnel.ssh_tunnel(lp, rp, sshserver, remote_ip, sshkey, password)
364
364
365 return tuple(lports)
365 return tuple(lports)
366
366
367
367
@@ -383,9 +383,9 b' class ConnectionFileMixin(LoggingConfigurable):'
383 """Mixin for configurable classes that work with connection files"""
383 """Mixin for configurable classes that work with connection files"""
384
384
385 # The addresses for the communication channels
385 # The addresses for the communication channels
386 connection_file = Unicode('', config=True,
386 connection_file = Unicode('', config=True,
387 help="""JSON file in which to store connection info [default: kernel-<pid>.json]
387 help="""JSON file in which to store connection info [default: kernel-<pid>.json]
388
388
389 This file will contain the IP, ports, and authentication key needed to connect
389 This file will contain the IP, ports, and authentication key needed to connect
390 clients to this kernel. By default, this file will be created in the security dir
390 clients to this kernel. By default, this file will be created in the security dir
391 of the current profile, but can be specified by absolute path.
391 of the current profile, but can be specified by absolute path.
@@ -504,12 +504,12 b' class ConnectionFileMixin(LoggingConfigurable):'
504 cfg = json.load(f)
504 cfg = json.load(f)
505 self.transport = cfg.get('transport', self.transport)
505 self.transport = cfg.get('transport', self.transport)
506 self.ip = cfg.get('ip', self._ip_default())
506 self.ip = cfg.get('ip', self._ip_default())
507
507
508 for name in port_names:
508 for name in port_names:
509 if getattr(self, name) == 0 and name in cfg:
509 if getattr(self, name) == 0 and name in cfg:
510 # not overridden by config or cl_args
510 # not overridden by config or cl_args
511 setattr(self, name, cfg[name])
511 setattr(self, name, cfg[name])
512
512
513 if 'key' in cfg:
513 if 'key' in cfg:
514 self.session.key = str_to_bytes(cfg['key'])
514 self.session.key = str_to_bytes(cfg['key'])
515 if 'signature_scheme' in cfg:
515 if 'signature_scheme' in cfg:
1 NO CONTENT: file renamed from IPython/kernel/ioloop/__init__.py to jupyter_client/ioloop/__init__.py
NO CONTENT: file renamed from IPython/kernel/ioloop/__init__.py to jupyter_client/ioloop/__init__.py
1 NO CONTENT: file renamed from IPython/kernel/ioloop/manager.py to jupyter_client/ioloop/manager.py
NO CONTENT: file renamed from IPython/kernel/ioloop/manager.py to jupyter_client/ioloop/manager.py
@@ -51,4 +51,3 b' class IOLoopKernelRestarter(KernelRestarter):'
51 if self._pcallback is not None:
51 if self._pcallback is not None:
52 self._pcallback.stop()
52 self._pcallback.stop()
53 self._pcallback = None
53 self._pcallback = None
54
@@ -22,7 +22,7 b' else:'
22 SYSTEM_KERNEL_DIRS = ["/usr/share/jupyter/kernels",
22 SYSTEM_KERNEL_DIRS = ["/usr/share/jupyter/kernels",
23 "/usr/local/share/jupyter/kernels",
23 "/usr/local/share/jupyter/kernels",
24 ]
24 ]
25
25
26 NATIVE_KERNEL_NAME = 'python3' if PY3 else 'python2'
26 NATIVE_KERNEL_NAME = 'python3' if PY3 else 'python2'
27
27
28 def _pythonfirst(s):
28 def _pythonfirst(s):
@@ -40,18 +40,18 b' class KernelSpec(HasTraits):'
40 language = Unicode()
40 language = Unicode()
41 env = Dict()
41 env = Dict()
42 resource_dir = Unicode()
42 resource_dir = Unicode()
43
43
44 @classmethod
44 @classmethod
45 def from_resource_dir(cls, resource_dir):
45 def from_resource_dir(cls, resource_dir):
46 """Create a KernelSpec object by reading kernel.json
46 """Create a KernelSpec object by reading kernel.json
47
47
48 Pass the path to the *directory* containing kernel.json.
48 Pass the path to the *directory* containing kernel.json.
49 """
49 """
50 kernel_file = pjoin(resource_dir, 'kernel.json')
50 kernel_file = pjoin(resource_dir, 'kernel.json')
51 with io.open(kernel_file, 'r', encoding='utf-8') as f:
51 with io.open(kernel_file, 'r', encoding='utf-8') as f:
52 kernel_dict = json.load(f)
52 kernel_dict = json.load(f)
53 return cls(resource_dir=resource_dir, **kernel_dict)
53 return cls(resource_dir=resource_dir, **kernel_dict)
54
54
55 def to_dict(self):
55 def to_dict(self):
56 d = dict(argv=self.argv,
56 d = dict(argv=self.argv,
57 env=self.env,
57 env=self.env,
@@ -70,7 +70,7 b' def _is_kernel_dir(path):'
70
70
71 def _list_kernels_in(dir):
71 def _list_kernels_in(dir):
72 """Return a mapping of kernel names to resource directories from dir.
72 """Return a mapping of kernel names to resource directories from dir.
73
73
74 If dir is None or does not exist, returns an empty dict.
74 If dir is None or does not exist, returns an empty dict.
75 """
75 """
76 if dir is None or not os.path.isdir(dir):
76 if dir is None or not os.path.isdir(dir):
@@ -94,15 +94,15 b' class KernelSpecManager(Configurable):'
94 @property
94 @property
95 def env_kernel_dir(self):
95 def env_kernel_dir(self):
96 return pjoin(sys.prefix, 'share', 'jupyter', 'kernels')
96 return pjoin(sys.prefix, 'share', 'jupyter', 'kernels')
97
97
98 whitelist = Set(config=True,
98 whitelist = Set(config=True,
99 help="""Whitelist of allowed kernel names.
99 help="""Whitelist of allowed kernel names.
100
100
101 By default, all installed kernels are allowed.
101 By default, all installed kernels are allowed.
102 """
102 """
103 )
103 )
104 kernel_dirs = List(
104 kernel_dirs = List(
105 help="List of kernel directories to search. Later ones take priority over earlier."
105 help="List of kernel directories to search. Later ones take priority over earlier."
106 )
106 )
107 def _kernel_dirs_default(self):
107 def _kernel_dirs_default(self):
108 dirs = SYSTEM_KERNEL_DIRS[:]
108 dirs = SYSTEM_KERNEL_DIRS[:]
@@ -114,7 +114,7 b' class KernelSpecManager(Configurable):'
114 @property
114 @property
115 def _native_kernel_dict(self):
115 def _native_kernel_dict(self):
116 """Makes a kernel directory for the native kernel.
116 """Makes a kernel directory for the native kernel.
117
117
118 The native kernel is the kernel using the same Python runtime as this
118 The native kernel is the kernel using the same Python runtime as this
119 process. This will put its information in the user kernels directory.
119 process. This will put its information in the user kernels directory.
120 """
120 """
@@ -143,7 +143,7 b' class KernelSpecManager(Configurable):'
143
143
144 def get_kernel_spec(self, kernel_name):
144 def get_kernel_spec(self, kernel_name):
145 """Returns a :class:`KernelSpec` instance for the given kernel_name.
145 """Returns a :class:`KernelSpec` instance for the given kernel_name.
146
146
147 Raises :exc:`NoSuchKernel` if the given kernel name is not found.
147 Raises :exc:`NoSuchKernel` if the given kernel name is not found.
148 """
148 """
149 if kernel_name in {'python', NATIVE_KERNEL_NAME} and \
149 if kernel_name in {'python', NATIVE_KERNEL_NAME} and \
@@ -157,7 +157,7 b' class KernelSpecManager(Configurable):'
157 except KeyError:
157 except KeyError:
158 raise NoSuchKernel(kernel_name)
158 raise NoSuchKernel(kernel_name)
159 return KernelSpec.from_resource_dir(resource_dir)
159 return KernelSpec.from_resource_dir(resource_dir)
160
160
161 def _get_destination_dir(self, kernel_name, user=False):
161 def _get_destination_dir(self, kernel_name, user=False):
162 if user:
162 if user:
163 return os.path.join(self.user_kernel_dir, kernel_name)
163 return os.path.join(self.user_kernel_dir, kernel_name)
@@ -171,14 +171,14 b' class KernelSpecManager(Configurable):'
171 def install_kernel_spec(self, source_dir, kernel_name=None, user=False,
171 def install_kernel_spec(self, source_dir, kernel_name=None, user=False,
172 replace=False):
172 replace=False):
173 """Install a kernel spec by copying its directory.
173 """Install a kernel spec by copying its directory.
174
174
175 If ``kernel_name`` is not given, the basename of ``source_dir`` will
175 If ``kernel_name`` is not given, the basename of ``source_dir`` will
176 be used.
176 be used.
177
177
178 If ``user`` is False, it will attempt to install into the systemwide
178 If ``user`` is False, it will attempt to install into the systemwide
179 kernel registry. If the process does not have appropriate permissions,
179 kernel registry. If the process does not have appropriate permissions,
180 an :exc:`OSError` will be raised.
180 an :exc:`OSError` will be raised.
181
181
182 If ``replace`` is True, this will replace an existing kernel of the same
182 If ``replace`` is True, this will replace an existing kernel of the same
183 name. Otherwise, if the destination already exists, an :exc:`OSError`
183 name. Otherwise, if the destination already exists, an :exc:`OSError`
184 will be raised.
184 will be raised.
@@ -186,7 +186,7 b' class KernelSpecManager(Configurable):'
186 if not kernel_name:
186 if not kernel_name:
187 kernel_name = os.path.basename(source_dir)
187 kernel_name = os.path.basename(source_dir)
188 kernel_name = kernel_name.lower()
188 kernel_name = kernel_name.lower()
189
189
190 destination = self._get_destination_dir(kernel_name, user=user)
190 destination = self._get_destination_dir(kernel_name, user=user)
191
191
192 if replace and os.path.isdir(destination):
192 if replace and os.path.isdir(destination):
@@ -196,13 +196,13 b' class KernelSpecManager(Configurable):'
196
196
197 def install_native_kernel_spec(self, user=False):
197 def install_native_kernel_spec(self, user=False):
198 """Install the native kernel spec to the filesystem
198 """Install the native kernel spec to the filesystem
199
199
200 This allows a Python 3 frontend to use a Python 2 kernel, or vice versa.
200 This allows a Python 3 frontend to use a Python 2 kernel, or vice versa.
201 The kernelspec will be written pointing to the Python executable on
201 The kernelspec will be written pointing to the Python executable on
202 which this is run.
202 which this is run.
203
203
204 If ``user`` is False, it will attempt to install into the systemwide
204 If ``user`` is False, it will attempt to install into the systemwide
205 kernel registry. If the process does not have appropriate permissions,
205 kernel registry. If the process does not have appropriate permissions,
206 an :exc:`OSError` will be raised.
206 an :exc:`OSError` will be raised.
207 """
207 """
208 path = self._get_destination_dir(NATIVE_KERNEL_NAME, user=user)
208 path = self._get_destination_dir(NATIVE_KERNEL_NAME, user=user)
@@ -220,7 +220,7 b' def find_kernel_specs():'
220
220
221 def get_kernel_spec(kernel_name):
221 def get_kernel_spec(kernel_name):
222 """Returns a :class:`KernelSpec` instance for the given kernel_name.
222 """Returns a :class:`KernelSpec` instance for the given kernel_name.
223
223
224 Raises KeyError if the given kernel name is not found.
224 Raises KeyError if the given kernel name is not found.
225 """
225 """
226 return KernelSpecManager().get_kernel_spec(kernel_name)
226 return KernelSpecManager().get_kernel_spec(kernel_name)
1 NO CONTENT: file renamed from IPython/kernel/kernelspecapp.py to jupyter_client/kernelspecapp.py
NO CONTENT: file renamed from IPython/kernel/kernelspecapp.py to jupyter_client/kernelspecapp.py
@@ -14,35 +14,35 b' from IPython.utils.py3compat import cast_bytes_py2'
14
14
15 def swallow_argv(argv, aliases=None, flags=None):
15 def swallow_argv(argv, aliases=None, flags=None):
16 """strip frontend-specific aliases and flags from an argument list
16 """strip frontend-specific aliases and flags from an argument list
17
17
18 For use primarily in frontend apps that want to pass a subset of command-line
18 For use primarily in frontend apps that want to pass a subset of command-line
19 arguments through to a subprocess, where frontend-specific flags and aliases
19 arguments through to a subprocess, where frontend-specific flags and aliases
20 should be removed from the list.
20 should be removed from the list.
21
21
22 Parameters
22 Parameters
23 ----------
23 ----------
24
24
25 argv : list(str)
25 argv : list(str)
26 The starting argv, to be filtered
26 The starting argv, to be filtered
27 aliases : container of aliases (dict, list, set, etc.)
27 aliases : container of aliases (dict, list, set, etc.)
28 The frontend-specific aliases to be removed
28 The frontend-specific aliases to be removed
29 flags : container of flags (dict, list, set, etc.)
29 flags : container of flags (dict, list, set, etc.)
30 The frontend-specific flags to be removed
30 The frontend-specific flags to be removed
31
31
32 Returns
32 Returns
33 -------
33 -------
34
34
35 argv : list(str)
35 argv : list(str)
36 The argv list, excluding flags and aliases that have been stripped
36 The argv list, excluding flags and aliases that have been stripped
37 """
37 """
38
38
39 if aliases is None:
39 if aliases is None:
40 aliases = set()
40 aliases = set()
41 if flags is None:
41 if flags is None:
42 flags = set()
42 flags = set()
43
43
44 stripped = list(argv) # copy
44 stripped = list(argv) # copy
45
45
46 swallow_next = False
46 swallow_next = False
47 was_flag = False
47 was_flag = False
48 for a in argv:
48 for a in argv:
@@ -73,7 +73,7 b' def swallow_argv(argv, aliases=None, flags=None):'
73 elif len(split) == 1 and any(flag.startswith(name) for flag in flags):
73 elif len(split) == 1 and any(flag.startswith(name) for flag in flags):
74 # strip flag, but don't swallow next, as flags don't take args
74 # strip flag, but don't swallow next, as flags don't take args
75 stripped.remove(a)
75 stripped.remove(a)
76
76
77 # return shortened list
77 # return shortened list
78 return stripped
78 return stripped
79
79
@@ -91,17 +91,17 b" def make_ipkernel_cmd(mod='IPython.kernel', executable=None, extra_arguments=[],"
91
91
92 extra_arguments : list, optional
92 extra_arguments : list, optional
93 A list of extra arguments to pass when executing the launch code.
93 A list of extra arguments to pass when executing the launch code.
94
94
95 Returns
95 Returns
96 -------
96 -------
97
97
98 A Popen command list
98 A Popen command list
99 """
99 """
100 if executable is None:
100 if executable is None:
101 executable = sys.executable
101 executable = sys.executable
102 arguments = [ executable, '-m', mod, '-f', '{connection_file}' ]
102 arguments = [ executable, '-m', mod, '-f', '{connection_file}' ]
103 arguments.extend(extra_arguments)
103 arguments.extend(extra_arguments)
104
104
105 return arguments
105 return arguments
106
106
107
107
@@ -131,7 +131,7 b' def launch_kernel(cmd, stdin=None, stdout=None, stderr=None, env=None,'
131
131
132 Returns
132 Returns
133 -------
133 -------
134
134
135 Popen instance for the kernel subprocess
135 Popen instance for the kernel subprocess
136 """
136 """
137
137
@@ -155,7 +155,7 b' def launch_kernel(cmd, stdin=None, stdout=None, stderr=None, env=None,'
155 _stderr = blackhole if stderr is None else stderr
155 _stderr = blackhole if stderr is None else stderr
156 else:
156 else:
157 _stdout, _stderr = stdout, stderr
157 _stdout, _stderr = stdout, stderr
158
158
159 env = env if (env is not None) else os.environ.copy()
159 env = env if (env is not None) else os.environ.copy()
160
160
161 encoding = getdefaultencoding(prefer_stream=False)
161 encoding = getdefaultencoding(prefer_stream=False)
@@ -166,7 +166,7 b' def launch_kernel(cmd, stdin=None, stdout=None, stderr=None, env=None,'
166 cwd=cwd,
166 cwd=cwd,
167 env=env,
167 env=env,
168 )
168 )
169
169
170 # Spawn a kernel.
170 # Spawn a kernel.
171 if sys.platform == 'win32':
171 if sys.platform == 'win32':
172 # Popen on Python 2 on Windows cannot handle unicode args or cwd
172 # Popen on Python 2 on Windows cannot handle unicode args or cwd
@@ -174,7 +174,7 b' def launch_kernel(cmd, stdin=None, stdout=None, stderr=None, env=None,'
174 if cwd:
174 if cwd:
175 cwd = cast_bytes_py2(cwd, sys.getfilesystemencoding() or 'ascii')
175 cwd = cast_bytes_py2(cwd, sys.getfilesystemencoding() or 'ascii')
176 kwargs['cwd'] = cwd
176 kwargs['cwd'] = cwd
177
177
178 from IPython.kernel.zmq.parentpoller import ParentPollerWindows
178 from IPython.kernel.zmq.parentpoller import ParentPollerWindows
179 # Create a Win32 event for interrupting the kernel
179 # Create a Win32 event for interrupting the kernel
180 # and store it in an environment variable.
180 # and store it in an environment variable.
@@ -198,7 +198,7 b' def launch_kernel(cmd, stdin=None, stdout=None, stderr=None, env=None,'
198 True, # Inheritable by new processes.
198 True, # Inheritable by new processes.
199 DUPLICATE_SAME_ACCESS)
199 DUPLICATE_SAME_ACCESS)
200 env['JPY_PARENT_PID'] = str(int(handle))
200 env['JPY_PARENT_PID'] = str(int(handle))
201
201
202 proc = Popen(cmd, **kwargs)
202 proc = Popen(cmd, **kwargs)
203
203
204 # Attach the interrupt event to the Popen objet so it can be used later.
204 # Attach the interrupt event to the Popen objet so it can be used later.
@@ -209,7 +209,7 b' def launch_kernel(cmd, stdin=None, stdout=None, stderr=None, env=None,'
209 kwargs['preexec_fn'] = lambda: os.setsid()
209 kwargs['preexec_fn'] = lambda: os.setsid()
210 else:
210 else:
211 env['JPY_PARENT_PID'] = str(os.getpid())
211 env['JPY_PARENT_PID'] = str(os.getpid())
212
212
213 proc = Popen(cmd, **kwargs)
213 proc = Popen(cmd, **kwargs)
214
214
215 # Clean up pipes created to work around Popen bug.
215 # Clean up pipes created to work around Popen bug.
@@ -56,19 +56,19 b' class KernelManager(ConnectionFileMixin):'
56 # The kernel process with which the KernelManager is communicating.
56 # The kernel process with which the KernelManager is communicating.
57 # generally a Popen instance
57 # generally a Popen instance
58 kernel = Any()
58 kernel = Any()
59
59
60 kernel_spec_manager = Instance(kernelspec.KernelSpecManager)
60 kernel_spec_manager = Instance(kernelspec.KernelSpecManager)
61
61
62 def _kernel_spec_manager_default(self):
62 def _kernel_spec_manager_default(self):
63 return kernelspec.KernelSpecManager(ipython_dir=self.ipython_dir)
63 return kernelspec.KernelSpecManager(ipython_dir=self.ipython_dir)
64
64
65 kernel_name = Unicode(kernelspec.NATIVE_KERNEL_NAME)
65 kernel_name = Unicode(kernelspec.NATIVE_KERNEL_NAME)
66
66
67 kernel_spec = Instance(kernelspec.KernelSpec)
67 kernel_spec = Instance(kernelspec.KernelSpec)
68
68
69 def _kernel_spec_default(self):
69 def _kernel_spec_default(self):
70 return self.kernel_spec_manager.get_kernel_spec(self.kernel_name)
70 return self.kernel_spec_manager.get_kernel_spec(self.kernel_name)
71
71
72 def _kernel_name_changed(self, name, old, new):
72 def _kernel_name_changed(self, name, old, new):
73 if new == 'python':
73 if new == 'python':
74 self.kernel_name = kernelspec.NATIVE_KERNEL_NAME
74 self.kernel_name = kernelspec.NATIVE_KERNEL_NAME
@@ -79,12 +79,12 b' class KernelManager(ConnectionFileMixin):'
79
79
80 kernel_cmd = List(Unicode, config=True,
80 kernel_cmd = List(Unicode, config=True,
81 help="""DEPRECATED: Use kernel_name instead.
81 help="""DEPRECATED: Use kernel_name instead.
82
82
83 The Popen Command to launch the kernel.
83 The Popen Command to launch the kernel.
84 Override this if you have a custom kernel.
84 Override this if you have a custom kernel.
85 If kernel_cmd is specified in a configuration file,
85 If kernel_cmd is specified in a configuration file,
86 IPython does not pass any arguments to the kernel,
86 IPython does not pass any arguments to the kernel,
87 because it cannot make any assumptions about the
87 because it cannot make any assumptions about the
88 arguments that the kernel understands. In particular,
88 arguments that the kernel understands. In particular,
89 this means that the kernel does not receive the
89 this means that the kernel does not receive the
90 option --debug if it given on the IPython command line.
90 option --debug if it given on the IPython command line.
@@ -97,7 +97,7 b' class KernelManager(ConnectionFileMixin):'
97 self.ipython_kernel = False
97 self.ipython_kernel = False
98
98
99 ipython_kernel = Bool(True)
99 ipython_kernel = Bool(True)
100
100
101 ipython_dir = Unicode()
101 ipython_dir = Unicode()
102 def _ipython_dir_default(self):
102 def _ipython_dir_default(self):
103 return get_ipython_dir()
103 return get_ipython_dir()
@@ -173,12 +173,12 b' class KernelManager(ConnectionFileMixin):'
173
173
174 ns = dict(connection_file=self.connection_file)
174 ns = dict(connection_file=self.connection_file)
175 ns.update(self._launch_args)
175 ns.update(self._launch_args)
176
176
177 pat = re.compile(r'\{([A-Za-z0-9_]+)\}')
177 pat = re.compile(r'\{([A-Za-z0-9_]+)\}')
178 def from_ns(match):
178 def from_ns(match):
179 """Get the key out of ns if it's there, otherwise no change."""
179 """Get the key out of ns if it's there, otherwise no change."""
180 return ns.get(match.group(1), match.group())
180 return ns.get(match.group(1), match.group())
181
181
182 return [ pat.sub(from_ns, arg) for arg in cmd ]
182 return [ pat.sub(from_ns, arg) for arg in cmd ]
183
183
184 def _launch_kernel(self, kernel_cmd, **kw):
184 def _launch_kernel(self, kernel_cmd, **kw):
@@ -243,7 +243,7 b' class KernelManager(ConnectionFileMixin):'
243
243
244 def request_shutdown(self, restart=False):
244 def request_shutdown(self, restart=False):
245 """Send a shutdown request via control channel
245 """Send a shutdown request via control channel
246
246
247 On Windows, this just kills kernels instead, because the shutdown
247 On Windows, this just kills kernels instead, because the shutdown
248 messages don't work.
248 messages don't work.
249 """
249 """
@@ -253,7 +253,7 b' class KernelManager(ConnectionFileMixin):'
253
253
254 def finish_shutdown(self, waittime=1, pollinterval=0.1):
254 def finish_shutdown(self, waittime=1, pollinterval=0.1):
255 """Wait for kernel shutdown, then kill process if it doesn't shutdown.
255 """Wait for kernel shutdown, then kill process if it doesn't shutdown.
256
256
257 This does not send shutdown requests - use :meth:`request_shutdown`
257 This does not send shutdown requests - use :meth:`request_shutdown`
258 first.
258 first.
259 """
259 """
@@ -427,9 +427,9 b" def start_new_kernel(startup_timeout=60, kernel_name='python', **kwargs):"
427 @contextmanager
427 @contextmanager
428 def run_kernel(**kwargs):
428 def run_kernel(**kwargs):
429 """Context manager to create a kernel in a subprocess.
429 """Context manager to create a kernel in a subprocess.
430
430
431 The kernel is shut down when the context exits.
431 The kernel is shut down when the context exits.
432
432
433 Returns
433 Returns
434 -------
434 -------
435 kernel_client: connected KernelClient instance
435 kernel_client: connected KernelClient instance
1 NO CONTENT: file renamed from IPython/kernel/managerabc.py to jupyter_client/managerabc.py
NO CONTENT: file renamed from IPython/kernel/managerabc.py to jupyter_client/managerabc.py
@@ -41,13 +41,13 b' def kernel_method(f):'
41
41
42 class MultiKernelManager(LoggingConfigurable):
42 class MultiKernelManager(LoggingConfigurable):
43 """A class for managing multiple kernels."""
43 """A class for managing multiple kernels."""
44
44
45 ipython_kernel_argv = List(Unicode)
45 ipython_kernel_argv = List(Unicode)
46
46
47 default_kernel_name = Unicode(NATIVE_KERNEL_NAME, config=True,
47 default_kernel_name = Unicode(NATIVE_KERNEL_NAME, config=True,
48 help="The name of the default kernel to start"
48 help="The name of the default kernel to start"
49 )
49 )
50
50
51 kernel_manager_class = DottedObjectName(
51 kernel_manager_class = DottedObjectName(
52 "IPython.kernel.ioloop.IOLoopKernelManager", config=True,
52 "IPython.kernel.ioloop.IOLoopKernelManager", config=True,
53 help="""The kernel manager class. This is configurable to allow
53 help="""The kernel manager class. This is configurable to allow
@@ -56,11 +56,11 b' class MultiKernelManager(LoggingConfigurable):'
56 )
56 )
57 def _kernel_manager_class_changed(self, name, old, new):
57 def _kernel_manager_class_changed(self, name, old, new):
58 self.kernel_manager_factory = import_item(new)
58 self.kernel_manager_factory = import_item(new)
59
59
60 kernel_manager_factory = Any(help="this is kernel_manager_class after import")
60 kernel_manager_factory = Any(help="this is kernel_manager_class after import")
61 def _kernel_manager_factory_default(self):
61 def _kernel_manager_factory_default(self):
62 return import_item(self.kernel_manager_class)
62 return import_item(self.kernel_manager_class)
63
63
64 context = Instance('zmq.Context')
64 context = Instance('zmq.Context')
65 def _context_default(self):
65 def _context_default(self):
66 return zmq.Context.instance()
66 return zmq.Context.instance()
@@ -96,7 +96,7 b' class MultiKernelManager(LoggingConfigurable):'
96 kernel_id = kwargs.pop('kernel_id', unicode_type(uuid.uuid4()))
96 kernel_id = kwargs.pop('kernel_id', unicode_type(uuid.uuid4()))
97 if kernel_id in self:
97 if kernel_id in self:
98 raise DuplicateKernelError('Kernel already exists: %s' % kernel_id)
98 raise DuplicateKernelError('Kernel already exists: %s' % kernel_id)
99
99
100 if kernel_name is None:
100 if kernel_name is None:
101 kernel_name = self.default_kernel_name
101 kernel_name = self.default_kernel_name
102 # kernel_manager_factory is the constructor for the KernelManager
102 # kernel_manager_factory is the constructor for the KernelManager
@@ -19,14 +19,14 b' class KernelRestarter(LoggingConfigurable):'
19 """Monitor and autorestart a kernel."""
19 """Monitor and autorestart a kernel."""
20
20
21 kernel_manager = Instance('IPython.kernel.KernelManager')
21 kernel_manager = Instance('IPython.kernel.KernelManager')
22
22
23 debug = Bool(False, config=True,
23 debug = Bool(False, config=True,
24 help="""Whether to include every poll event in debugging output.
24 help="""Whether to include every poll event in debugging output.
25
25
26 Has to be set explicitly, because there will be *a lot* of output.
26 Has to be set explicitly, because there will be *a lot* of output.
27 """
27 """
28 )
28 )
29
29
30 time_to_dead = Float(3.0, config=True,
30 time_to_dead = Float(3.0, config=True,
31 help="""Kernel heartbeat interval in seconds."""
31 help="""Kernel heartbeat interval in seconds."""
32 )
32 )
@@ -118,7 +118,7 b' session_flags = {'
118
118
119 def default_secure(cfg):
119 def default_secure(cfg):
120 """Set the default behavior for a config environment to be secure.
120 """Set the default behavior for a config environment to be secure.
121
121
122 If Session.key/keyfile have not been set, set Session.key to
122 If Session.key/keyfile have not been set, set Session.key to
123 a new random UUID.
123 a new random UUID.
124 """
124 """
@@ -310,20 +310,20 b' class Session(Configurable):'
310
310
311 metadata = Dict({}, config=True,
311 metadata = Dict({}, config=True,
312 help="""Metadata dictionary, which serves as the default top-level metadata dict for each message.""")
312 help="""Metadata dictionary, which serves as the default top-level metadata dict for each message.""")
313
313
314 # if 0, no adapting to do.
314 # if 0, no adapting to do.
315 adapt_version = Integer(0)
315 adapt_version = Integer(0)
316
316
317 # message signature related traits:
317 # message signature related traits:
318
318
319 key = CBytes(config=True,
319 key = CBytes(config=True,
320 help="""execution key, for signing messages.""")
320 help="""execution key, for signing messages.""")
321 def _key_default(self):
321 def _key_default(self):
322 return str_to_bytes(str(uuid.uuid4()))
322 return str_to_bytes(str(uuid.uuid4()))
323
323
324 def _key_changed(self):
324 def _key_changed(self):
325 self._new_auth()
325 self._new_auth()
326
326
327 signature_scheme = Unicode('hmac-sha256', config=True,
327 signature_scheme = Unicode('hmac-sha256', config=True,
328 help="""The digest scheme used to construct the message signatures.
328 help="""The digest scheme used to construct the message signatures.
329 Must have the form 'hmac-HASH'.""")
329 Must have the form 'hmac-HASH'.""")
@@ -336,7 +336,7 b' class Session(Configurable):'
336 except AttributeError:
336 except AttributeError:
337 raise TraitError("hashlib has no such attribute: %s" % hash_name)
337 raise TraitError("hashlib has no such attribute: %s" % hash_name)
338 self._new_auth()
338 self._new_auth()
339
339
340 digest_mod = Any()
340 digest_mod = Any()
341 def _digest_mod_default(self):
341 def _digest_mod_default(self):
342 return hashlib.sha256
342 return hashlib.sha256
@@ -348,11 +348,11 b' class Session(Configurable):'
348 self.auth = hmac.HMAC(self.key, digestmod=self.digest_mod)
348 self.auth = hmac.HMAC(self.key, digestmod=self.digest_mod)
349 else:
349 else:
350 self.auth = None
350 self.auth = None
351
351
352 digest_history = Set()
352 digest_history = Set()
353 digest_history_size = Integer(2**16, config=True,
353 digest_history_size = Integer(2**16, config=True,
354 help="""The maximum number of digests to remember.
354 help="""The maximum number of digests to remember.
355
355
356 The digest history will be culled when it exceeds this value.
356 The digest history will be culled when it exceeds this value.
357 """
357 """
358 )
358 )
@@ -365,9 +365,9 b' class Session(Configurable):'
365
365
366 # for protecting against sends from forks
366 # for protecting against sends from forks
367 pid = Integer()
367 pid = Integer()
368
368
369 # serialization traits:
369 # serialization traits:
370
370
371 pack = Any(default_packer) # the actual packer function
371 pack = Any(default_packer) # the actual packer function
372 def _pack_changed(self, name, old, new):
372 def _pack_changed(self, name, old, new):
373 if not callable(new):
373 if not callable(new):
@@ -378,7 +378,7 b' class Session(Configurable):'
378 # unpacker is not checked - it is assumed to be
378 # unpacker is not checked - it is assumed to be
379 if not callable(new):
379 if not callable(new):
380 raise TypeError("unpacker must be callable, not %s"%type(new))
380 raise TypeError("unpacker must be callable, not %s"%type(new))
381
381
382 # thresholds:
382 # thresholds:
383 copy_threshold = Integer(2**16, config=True,
383 copy_threshold = Integer(2**16, config=True,
384 help="Threshold (in bytes) beyond which a buffer should be sent without copying.")
384 help="Threshold (in bytes) beyond which a buffer should be sent without copying.")
@@ -390,7 +390,7 b' class Session(Configurable):'
390 """
390 """
391 )
391 )
392
392
393
393
394 def __init__(self, **kwargs):
394 def __init__(self, **kwargs):
395 """create a Session object
395 """create a Session object
396
396
@@ -625,7 +625,7 b' class Session(Configurable):'
625 track : bool
625 track : bool
626 Whether to track. Only for use with Sockets, because ZMQStream
626 Whether to track. Only for use with Sockets, because ZMQStream
627 objects cannot track messages.
627 objects cannot track messages.
628
628
629
629
630 Returns
630 Returns
631 -------
631 -------
@@ -655,7 +655,7 b' class Session(Configurable):'
655 to_send.extend(buffers)
655 to_send.extend(buffers)
656 longest = max([ len(s) for s in to_send ])
656 longest = max([ len(s) for s in to_send ])
657 copy = (longest < self.copy_threshold)
657 copy = (longest < self.copy_threshold)
658
658
659 if buffers and track and not copy:
659 if buffers and track and not copy:
660 # only really track when we are doing zero-copy buffers
660 # only really track when we are doing zero-copy buffers
661 tracker = stream.send_multipart(to_send, copy=False, track=True)
661 tracker = stream.send_multipart(to_send, copy=False, track=True)
@@ -776,15 +776,15 b' class Session(Configurable):'
776 if self.digest_history_size == 0:
776 if self.digest_history_size == 0:
777 # no history, never add digests
777 # no history, never add digests
778 return
778 return
779
779
780 self.digest_history.add(signature)
780 self.digest_history.add(signature)
781 if len(self.digest_history) > self.digest_history_size:
781 if len(self.digest_history) > self.digest_history_size:
782 # threshold reached, cull 10%
782 # threshold reached, cull 10%
783 self._cull_digest_history()
783 self._cull_digest_history()
784
784
785 def _cull_digest_history(self):
785 def _cull_digest_history(self):
786 """cull the digest history
786 """cull the digest history
787
787
788 Removes a randomly selected 10% of the digest history
788 Removes a randomly selected 10% of the digest history
789 """
789 """
790 current = len(self.digest_history)
790 current = len(self.digest_history)
@@ -794,7 +794,7 b' class Session(Configurable):'
794 return
794 return
795 to_cull = random.sample(self.digest_history, n_to_cull)
795 to_cull = random.sample(self.digest_history, n_to_cull)
796 self.digest_history.difference_update(to_cull)
796 self.digest_history.difference_update(to_cull)
797
797
798 def deserialize(self, msg_list, content=True, copy=True):
798 def deserialize(self, msg_list, content=True, copy=True):
799 """Unserialize a msg_list to a nested message dict.
799 """Unserialize a msg_list to a nested message dict.
800
800
@@ -855,7 +855,7 b' class Session(Configurable):'
855 message['buffers'] = buffers
855 message['buffers'] = buffers
856 # adapt to the current version
856 # adapt to the current version
857 return adapt(message)
857 return adapt(message)
858
858
859 def unserialize(self, *args, **kwargs):
859 def unserialize(self, *args, **kwargs):
860 warnings.warn(
860 warnings.warn(
861 "Session.unserialize is deprecated. Use Session.deserialize.",
861 "Session.unserialize is deprecated. Use Session.deserialize.",
@@ -879,4 +879,3 b' def test_msg2obj():'
879 am2 = dict(ao)
879 am2 = dict(ao)
880 assert am['x'] == am2['x']
880 assert am['x'] == am2['x']
881 assert am['y']['z'] == am2['y']['z']
881 assert am['y']['z'] == am2['y']['z']
882
@@ -26,15 +26,15 b' def test_code_to_line_no_code():'
26 nt.assert_equal(pos, 0)
26 nt.assert_equal(pos, 0)
27
27
28 class AdapterTest(TestCase):
28 class AdapterTest(TestCase):
29
29
30 def setUp(self):
30 def setUp(self):
31 self.session = Session()
31 self.session = Session()
32
32
33 def adapt(self, msg, version=None):
33 def adapt(self, msg, version=None):
34 original = copy.deepcopy(msg)
34 original = copy.deepcopy(msg)
35 adapted = adapt(msg, version or self.to_version)
35 adapted = adapt(msg, version or self.to_version)
36 return original, adapted
36 return original, adapted
37
37
38 def check_header(self, msg):
38 def check_header(self, msg):
39 pass
39 pass
40
40
@@ -42,28 +42,28 b' class AdapterTest(TestCase):'
42 class V4toV5TestCase(AdapterTest):
42 class V4toV5TestCase(AdapterTest):
43 from_version = 4
43 from_version = 4
44 to_version = 5
44 to_version = 5
45
45
46 def msg(self, msg_type, content):
46 def msg(self, msg_type, content):
47 """Create a v4 msg (same as v5, minus version header)"""
47 """Create a v4 msg (same as v5, minus version header)"""
48 msg = self.session.msg(msg_type, content)
48 msg = self.session.msg(msg_type, content)
49 msg['header'].pop('version')
49 msg['header'].pop('version')
50 return msg
50 return msg
51
51
52 def test_same_version(self):
52 def test_same_version(self):
53 msg = self.msg("execute_result",
53 msg = self.msg("execute_result",
54 content={'status' : 'ok'}
54 content={'status' : 'ok'}
55 )
55 )
56 original, adapted = self.adapt(msg, self.from_version)
56 original, adapted = self.adapt(msg, self.from_version)
57
57
58 self.assertEqual(original, adapted)
58 self.assertEqual(original, adapted)
59
59
60 def test_no_adapt(self):
60 def test_no_adapt(self):
61 msg = self.msg("input_reply", {'value' : 'some text'})
61 msg = self.msg("input_reply", {'value' : 'some text'})
62 v4, v5 = self.adapt(msg)
62 v4, v5 = self.adapt(msg)
63 self.assertEqual(v5['header']['version'], V4toV5.version)
63 self.assertEqual(v5['header']['version'], V4toV5.version)
64 v5['header'].pop('version')
64 v5['header'].pop('version')
65 self.assertEqual(v4, v5)
65 self.assertEqual(v4, v5)
66
66
67 def test_rename_type(self):
67 def test_rename_type(self):
68 for v5_type, v4_type in [
68 for v5_type, v4_type in [
69 ('execute_result', 'pyout'),
69 ('execute_result', 'pyout'),
@@ -75,7 +75,7 b' class V4toV5TestCase(AdapterTest):'
75 self.assertEqual(v5['header']['version'], V4toV5.version)
75 self.assertEqual(v5['header']['version'], V4toV5.version)
76 self.assertEqual(v5['header']['msg_type'], v5_type)
76 self.assertEqual(v5['header']['msg_type'], v5_type)
77 self.assertEqual(v4['content'], v5['content'])
77 self.assertEqual(v4['content'], v5['content'])
78
78
79 def test_execute_request(self):
79 def test_execute_request(self):
80 msg = self.msg("execute_request", {
80 msg = self.msg("execute_request", {
81 'code' : 'a=5',
81 'code' : 'a=5',
@@ -106,7 +106,7 b' class V4toV5TestCase(AdapterTest):'
106 self.assertEqual(v5c['payload'], [{'source': 'page',
106 self.assertEqual(v5c['payload'], [{'source': 'page',
107 'data': {'text/plain': 'blah'}}
107 'data': {'text/plain': 'blah'}}
108 ])
108 ])
109
109
110 def test_complete_request(self):
110 def test_complete_request(self):
111 msg = self.msg("complete_request", {
111 msg = self.msg("complete_request", {
112 'text' : 'a.is',
112 'text' : 'a.is',
@@ -121,7 +121,7 b' class V4toV5TestCase(AdapterTest):'
121 self.assertNotIn(key, v5c)
121 self.assertNotIn(key, v5c)
122 self.assertEqual(v5c['cursor_pos'], v4c['cursor_pos'])
122 self.assertEqual(v5c['cursor_pos'], v4c['cursor_pos'])
123 self.assertEqual(v5c['code'], v4c['line'])
123 self.assertEqual(v5c['code'], v4c['line'])
124
124
125 def test_complete_reply(self):
125 def test_complete_reply(self):
126 msg = self.msg("complete_reply", {
126 msg = self.msg("complete_reply", {
127 'matched_text' : 'a.is',
127 'matched_text' : 'a.is',
@@ -134,12 +134,12 b' class V4toV5TestCase(AdapterTest):'
134 v4, v5 = self.adapt(msg)
134 v4, v5 = self.adapt(msg)
135 v4c = v4['content']
135 v4c = v4['content']
136 v5c = v5['content']
136 v5c = v5['content']
137
137
138 self.assertEqual(v5c['matches'], v4c['matches'])
138 self.assertEqual(v5c['matches'], v4c['matches'])
139 self.assertEqual(v5c['metadata'], {})
139 self.assertEqual(v5c['metadata'], {})
140 self.assertEqual(v5c['cursor_start'], -4)
140 self.assertEqual(v5c['cursor_start'], -4)
141 self.assertEqual(v5c['cursor_end'], None)
141 self.assertEqual(v5c['cursor_end'], None)
142
142
143 def test_object_info_request(self):
143 def test_object_info_request(self):
144 msg = self.msg("object_info_request", {
144 msg = self.msg("object_info_request", {
145 'oname' : 'foo',
145 'oname' : 'foo',
@@ -152,7 +152,7 b' class V4toV5TestCase(AdapterTest):'
152 self.assertEqual(v5c['code'], v4c['oname'])
152 self.assertEqual(v5c['code'], v4c['oname'])
153 self.assertEqual(v5c['cursor_pos'], len(v4c['oname']))
153 self.assertEqual(v5c['cursor_pos'], len(v4c['oname']))
154 self.assertEqual(v5c['detail_level'], v4c['detail_level'])
154 self.assertEqual(v5c['detail_level'], v4c['detail_level'])
155
155
156 def test_object_info_reply(self):
156 def test_object_info_reply(self):
157 msg = self.msg("object_info_reply", {
157 msg = self.msg("object_info_reply", {
158 'oname' : 'foo',
158 'oname' : 'foo',
@@ -168,7 +168,7 b' class V4toV5TestCase(AdapterTest):'
168 self.assertEqual(sorted(v5c), [ 'data', 'found', 'metadata', 'name', 'status'])
168 self.assertEqual(sorted(v5c), [ 'data', 'found', 'metadata', 'name', 'status'])
169 text = v5c['data']['text/plain']
169 text = v5c['data']['text/plain']
170 self.assertEqual(text, '\n'.join([v4c['definition'], v4c['docstring']]))
170 self.assertEqual(text, '\n'.join([v4c['definition'], v4c['docstring']]))
171
171
172 def test_kernel_info_reply(self):
172 def test_kernel_info_reply(self):
173 msg = self.msg("kernel_info_reply", {
173 msg = self.msg("kernel_info_reply", {
174 'language': 'python',
174 'language': 'python',
@@ -188,9 +188,9 b' class V4toV5TestCase(AdapterTest):'
188 },
188 },
189 'banner' : '',
189 'banner' : '',
190 })
190 })
191
191
192 # iopub channel
192 # iopub channel
193
193
194 def test_display_data(self):
194 def test_display_data(self):
195 jsondata = dict(a=5)
195 jsondata = dict(a=5)
196 msg = self.msg("display_data", {
196 msg = self.msg("display_data", {
@@ -206,9 +206,9 b' class V4toV5TestCase(AdapterTest):'
206 self.assertEqual(v5c['metadata'], v4c['metadata'])
206 self.assertEqual(v5c['metadata'], v4c['metadata'])
207 self.assertEqual(v5c['data']['text/plain'], v4c['data']['text/plain'])
207 self.assertEqual(v5c['data']['text/plain'], v4c['data']['text/plain'])
208 self.assertEqual(v5c['data']['application/json'], jsondata)
208 self.assertEqual(v5c['data']['application/json'], jsondata)
209
209
210 # stdin channel
210 # stdin channel
211
211
212 def test_input_request(self):
212 def test_input_request(self):
213 msg = self.msg('input_request', {'prompt': "$>"})
213 msg = self.msg('input_request', {'prompt': "$>"})
214 v4, v5 = self.adapt(msg)
214 v4, v5 = self.adapt(msg)
@@ -219,25 +219,25 b' class V4toV5TestCase(AdapterTest):'
219 class V5toV4TestCase(AdapterTest):
219 class V5toV4TestCase(AdapterTest):
220 from_version = 5
220 from_version = 5
221 to_version = 4
221 to_version = 4
222
222
223 def msg(self, msg_type, content):
223 def msg(self, msg_type, content):
224 return self.session.msg(msg_type, content)
224 return self.session.msg(msg_type, content)
225
225
226 def test_same_version(self):
226 def test_same_version(self):
227 msg = self.msg("execute_result",
227 msg = self.msg("execute_result",
228 content={'status' : 'ok'}
228 content={'status' : 'ok'}
229 )
229 )
230 original, adapted = self.adapt(msg, self.from_version)
230 original, adapted = self.adapt(msg, self.from_version)
231
231
232 self.assertEqual(original, adapted)
232 self.assertEqual(original, adapted)
233
233
234 def test_no_adapt(self):
234 def test_no_adapt(self):
235 msg = self.msg("input_reply", {'value' : 'some text'})
235 msg = self.msg("input_reply", {'value' : 'some text'})
236 v5, v4 = self.adapt(msg)
236 v5, v4 = self.adapt(msg)
237 self.assertNotIn('version', v4['header'])
237 self.assertNotIn('version', v4['header'])
238 v5['header'].pop('version')
238 v5['header'].pop('version')
239 self.assertEqual(v4, v5)
239 self.assertEqual(v4, v5)
240
240
241 def test_rename_type(self):
241 def test_rename_type(self):
242 for v5_type, v4_type in [
242 for v5_type, v4_type in [
243 ('execute_result', 'pyout'),
243 ('execute_result', 'pyout'),
@@ -249,7 +249,7 b' class V5toV4TestCase(AdapterTest):'
249 self.assertEqual(v4['header']['msg_type'], v4_type)
249 self.assertEqual(v4['header']['msg_type'], v4_type)
250 nt.assert_not_in('version', v4['header'])
250 nt.assert_not_in('version', v4['header'])
251 self.assertEqual(v4['content'], v5['content'])
251 self.assertEqual(v4['content'], v5['content'])
252
252
253 def test_execute_request(self):
253 def test_execute_request(self):
254 msg = self.msg("execute_request", {
254 msg = self.msg("execute_request", {
255 'code' : 'a=5',
255 'code' : 'a=5',
@@ -262,7 +262,7 b' class V5toV4TestCase(AdapterTest):'
262 v5c = v5['content']
262 v5c = v5['content']
263 self.assertEqual(v4c['user_variables'], [])
263 self.assertEqual(v4c['user_variables'], [])
264 self.assertEqual(v5c['code'], v4c['code'])
264 self.assertEqual(v5c['code'], v4c['code'])
265
265
266 def test_complete_request(self):
266 def test_complete_request(self):
267 msg = self.msg("complete_request", {
267 msg = self.msg("complete_request", {
268 'code' : 'def foo():\n'
268 'code' : 'def foo():\n'
@@ -278,7 +278,7 b' class V5toV4TestCase(AdapterTest):'
278 self.assertEqual(v4c['cursor_pos'], 8)
278 self.assertEqual(v4c['cursor_pos'], 8)
279 self.assertEqual(v4c['text'], '')
279 self.assertEqual(v4c['text'], '')
280 self.assertEqual(v4c['block'], None)
280 self.assertEqual(v4c['block'], None)
281
281
282 def test_complete_reply(self):
282 def test_complete_reply(self):
283 msg = self.msg("complete_reply", {
283 msg = self.msg("complete_reply", {
284 'cursor_start' : 10,
284 'cursor_start' : 10,
@@ -295,7 +295,7 b' class V5toV4TestCase(AdapterTest):'
295 v5c = v5['content']
295 v5c = v5['content']
296 self.assertEqual(v4c['matched_text'], 'a.is')
296 self.assertEqual(v4c['matched_text'], 'a.is')
297 self.assertEqual(v4c['matches'], v5c['matches'])
297 self.assertEqual(v4c['matches'], v5c['matches'])
298
298
299 def test_inspect_request(self):
299 def test_inspect_request(self):
300 msg = self.msg("inspect_request", {
300 msg = self.msg("inspect_request", {
301 'code' : 'def foo():\n'
301 'code' : 'def foo():\n'
@@ -310,7 +310,7 b' class V5toV4TestCase(AdapterTest):'
310 v5c = v5['content']
310 v5c = v5['content']
311 self.assertEqual(v4c['oname'], 'apple')
311 self.assertEqual(v4c['oname'], 'apple')
312 self.assertEqual(v5c['detail_level'], v4c['detail_level'])
312 self.assertEqual(v5c['detail_level'], v4c['detail_level'])
313
313
314 def test_inspect_reply(self):
314 def test_inspect_reply(self):
315 msg = self.msg("inspect_reply", {
315 msg = self.msg("inspect_reply", {
316 'name' : 'foo',
316 'name' : 'foo',
@@ -324,7 +324,7 b' class V5toV4TestCase(AdapterTest):'
324 v5c = v5['content']
324 v5c = v5['content']
325 self.assertEqual(sorted(v4c), ['found', 'oname'])
325 self.assertEqual(sorted(v4c), ['found', 'oname'])
326 self.assertEqual(v4c['found'], False)
326 self.assertEqual(v4c['found'], False)
327
327
328 def test_kernel_info_reply(self):
328 def test_kernel_info_reply(self):
329 msg = self.msg("kernel_info_reply", {
329 msg = self.msg("kernel_info_reply", {
330 'protocol_version': '5.0',
330 'protocol_version': '5.0',
@@ -347,9 +347,9 b' class V5toV4TestCase(AdapterTest):'
347 'language_version': [2,8,0],
347 'language_version': [2,8,0],
348 'ipython_version': [1,2,3],
348 'ipython_version': [1,2,3],
349 })
349 })
350
350
351 # iopub channel
351 # iopub channel
352
352
353 def test_display_data(self):
353 def test_display_data(self):
354 jsondata = dict(a=5)
354 jsondata = dict(a=5)
355 msg = self.msg("display_data", {
355 msg = self.msg("display_data", {
@@ -365,13 +365,11 b' class V5toV4TestCase(AdapterTest):'
365 self.assertEqual(v5c['metadata'], v4c['metadata'])
365 self.assertEqual(v5c['metadata'], v4c['metadata'])
366 self.assertEqual(v5c['data']['text/plain'], v4c['data']['text/plain'])
366 self.assertEqual(v5c['data']['text/plain'], v4c['data']['text/plain'])
367 self.assertEqual(v4c['data']['application/json'], json.dumps(jsondata))
367 self.assertEqual(v4c['data']['application/json'], json.dumps(jsondata))
368
368
369 # stdin channel
369 # stdin channel
370
370
371 def test_input_request(self):
371 def test_input_request(self):
372 msg = self.msg('input_request', {'prompt': "$>", 'password' : True})
372 msg = self.msg('input_request', {'prompt': "$>", 'password' : True})
373 v5, v4 = self.adapt(msg)
373 v5, v4 = self.adapt(msg)
374 self.assertEqual(v5['content']['prompt'], v4['content']['prompt'])
374 self.assertEqual(v5['content']['prompt'], v4['content']['prompt'])
375 self.assertNotIn('password', v4['content'])
375 self.assertNotIn('password', v4['content'])
376
377
@@ -60,13 +60,13 b' def test_load_connection_file_session():'
60 app = DummyConsoleApp(session=Session())
60 app = DummyConsoleApp(session=Session())
61 app.initialize(argv=[])
61 app.initialize(argv=[])
62 session = app.session
62 session = app.session
63
63
64 with TemporaryDirectory() as d:
64 with TemporaryDirectory() as d:
65 cf = os.path.join(d, 'kernel.json')
65 cf = os.path.join(d, 'kernel.json')
66 connect.write_connection_file(cf, **sample_info)
66 connect.write_connection_file(cf, **sample_info)
67 app.connection_file = cf
67 app.connection_file = cf
68 app.load_connection_file()
68 app.load_connection_file()
69
69
70 nt.assert_equal(session.key, sample_info['key'])
70 nt.assert_equal(session.key, sample_info['key'])
71 nt.assert_equal(session.signature_scheme, sample_info['signature_scheme'])
71 nt.assert_equal(session.signature_scheme, sample_info['signature_scheme'])
72
72
@@ -78,7 +78,7 b' def test_app_load_connection_file():'
78 connect.write_connection_file(cf, **sample_info)
78 connect.write_connection_file(cf, **sample_info)
79 app = DummyConsoleApp(connection_file=cf)
79 app = DummyConsoleApp(connection_file=cf)
80 app.initialize(argv=[])
80 app.initialize(argv=[])
81
81
82 for attr, expected in sample_info.items():
82 for attr, expected in sample_info.items():
83 if attr in ('key', 'signature_scheme'):
83 if attr in ('key', 'signature_scheme'):
84 continue
84 continue
@@ -92,14 +92,14 b' def test_get_connection_file():'
92 cf = 'kernel.json'
92 cf = 'kernel.json'
93 app = DummyConsoleApp(config=cfg, connection_file=cf)
93 app = DummyConsoleApp(config=cfg, connection_file=cf)
94 app.initialize(argv=[])
94 app.initialize(argv=[])
95
95
96 profile_cf = os.path.join(app.profile_dir.location, 'security', cf)
96 profile_cf = os.path.join(app.profile_dir.location, 'security', cf)
97 nt.assert_equal(profile_cf, app.connection_file)
97 nt.assert_equal(profile_cf, app.connection_file)
98 with open(profile_cf, 'w') as f:
98 with open(profile_cf, 'w') as f:
99 f.write("{}")
99 f.write("{}")
100 nt.assert_true(os.path.exists(profile_cf))
100 nt.assert_true(os.path.exists(profile_cf))
101 nt.assert_equal(connect.get_connection_file(app), profile_cf)
101 nt.assert_equal(connect.get_connection_file(app), profile_cf)
102
102
103 app.connection_file = cf
103 app.connection_file = cf
104 nt.assert_equal(connect.get_connection_file(app), profile_cf)
104 nt.assert_equal(connect.get_connection_file(app), profile_cf)
105
105
@@ -111,11 +111,11 b' def test_find_connection_file():'
111 app = DummyConsoleApp(config=cfg, connection_file=cf)
111 app = DummyConsoleApp(config=cfg, connection_file=cf)
112 app.initialize(argv=[])
112 app.initialize(argv=[])
113 BaseIPythonApplication._instance = app
113 BaseIPythonApplication._instance = app
114
114
115 profile_cf = os.path.join(app.profile_dir.location, 'security', cf)
115 profile_cf = os.path.join(app.profile_dir.location, 'security', cf)
116 with open(profile_cf, 'w') as f:
116 with open(profile_cf, 'w') as f:
117 f.write("{}")
117 f.write("{}")
118
118
119 for query in (
119 for query in (
120 'kernel.json',
120 'kernel.json',
121 'kern*',
121 'kern*',
@@ -123,7 +123,7 b' def test_find_connection_file():'
123 'k*',
123 'k*',
124 ):
124 ):
125 nt.assert_equal(connect.find_connection_file(query), profile_cf)
125 nt.assert_equal(connect.find_connection_file(query), profile_cf)
126
126
127 BaseIPythonApplication._instance = None
127 BaseIPythonApplication._instance = None
128
128
129 def test_get_connection_info():
129 def test_get_connection_info():
@@ -132,12 +132,10 b' def test_get_connection_info():'
132 connect.write_connection_file(cf, **sample_info)
132 connect.write_connection_file(cf, **sample_info)
133 json_info = connect.get_connection_info(cf)
133 json_info = connect.get_connection_info(cf)
134 info = connect.get_connection_info(cf, unpack=True)
134 info = connect.get_connection_info(cf, unpack=True)
135
135
136 nt.assert_equal(type(json_info), type(""))
136 nt.assert_equal(type(json_info), type(""))
137 nt.assert_equal(info, sample_info)
137 nt.assert_equal(info, sample_info)
138
138
139 info2 = json.loads(json_info)
139 info2 = json.loads(json_info)
140 info2['key'] = str_to_bytes(info2['key'])
140 info2['key'] = str_to_bytes(info2['key'])
141 nt.assert_equal(info2, sample_info)
141 nt.assert_equal(info2, sample_info)
142
143
@@ -40,7 +40,7 b' class TestKernelManager(TestCase):'
40 def test_ipc_lifecycle(self):
40 def test_ipc_lifecycle(self):
41 km = self._get_ipc_km()
41 km = self._get_ipc_km()
42 self._run_lifecycle(km)
42 self._run_lifecycle(km)
43
43
44 def test_get_connect_info(self):
44 def test_get_connect_info(self):
45 km = self._get_tcp_km()
45 km = self._get_tcp_km()
46 cinfo = km.get_connection_info()
46 cinfo = km.get_connection_info()
@@ -51,4 +51,3 b' class TestKernelManager(TestCase):'
51 'key', 'signature_scheme',
51 'key', 'signature_scheme',
52 ])
52 ])
53 self.assertEqual(keys, expected)
53 self.assertEqual(keys, expected)
54
@@ -22,7 +22,7 b' class KernelSpecTests(unittest.TestCase):'
22 json.dump(sample_kernel_json, f)
22 json.dump(sample_kernel_json, f)
23
23
24 self.ksm = kernelspec.KernelSpecManager(ipython_dir=td.name)
24 self.ksm = kernelspec.KernelSpecManager(ipython_dir=td.name)
25
25
26 td2 = TemporaryDirectory()
26 td2 = TemporaryDirectory()
27 self.addCleanup(td2.cleanup)
27 self.addCleanup(td2.cleanup)
28 self.installable_kernel = td2.name
28 self.installable_kernel = td2.name
@@ -39,18 +39,18 b' class KernelSpecTests(unittest.TestCase):'
39 self.assertEqual(ks.argv, sample_kernel_json['argv'])
39 self.assertEqual(ks.argv, sample_kernel_json['argv'])
40 self.assertEqual(ks.display_name, sample_kernel_json['display_name'])
40 self.assertEqual(ks.display_name, sample_kernel_json['display_name'])
41 self.assertEqual(ks.env, {})
41 self.assertEqual(ks.env, {})
42
42
43 def test_install_kernel_spec(self):
43 def test_install_kernel_spec(self):
44 self.ksm.install_kernel_spec(self.installable_kernel,
44 self.ksm.install_kernel_spec(self.installable_kernel,
45 kernel_name='tstinstalled',
45 kernel_name='tstinstalled',
46 user=True)
46 user=True)
47 self.assertIn('tstinstalled', self.ksm.find_kernel_specs())
47 self.assertIn('tstinstalled', self.ksm.find_kernel_specs())
48
48
49 with self.assertRaises(OSError):
49 with self.assertRaises(OSError):
50 self.ksm.install_kernel_spec(self.installable_kernel,
50 self.ksm.install_kernel_spec(self.installable_kernel,
51 kernel_name='tstinstalled',
51 kernel_name='tstinstalled',
52 user=True)
52 user=True)
53
53
54 # Smoketest that this succeeds
54 # Smoketest that this succeeds
55 self.ksm.install_kernel_spec(self.installable_kernel,
55 self.ksm.install_kernel_spec(self.installable_kernel,
56 kernel_name='tstinstalled',
56 kernel_name='tstinstalled',
@@ -55,4 +55,3 b' def test_swallow_argv():'
55 "returned : %r" % stripped,
55 "returned : %r" % stripped,
56 ])
56 ])
57 nt.assert_equal(expected, stripped, message)
57 nt.assert_equal(expected, stripped, message)
58
@@ -61,7 +61,7 b' class TestKernelManager(TestCase):'
61 def test_tcp_lifecycle(self):
61 def test_tcp_lifecycle(self):
62 km = self._get_tcp_km()
62 km = self._get_tcp_km()
63 self._run_lifecycle(km)
63 self._run_lifecycle(km)
64
64
65 def test_shutdown_all(self):
65 def test_shutdown_all(self):
66 km = self._get_tcp_km()
66 km = self._get_tcp_km()
67 kid = km.start_kernel(stdout=PIPE, stderr=PIPE)
67 kid = km.start_kernel(stdout=PIPE, stderr=PIPE)
@@ -70,7 +70,7 b' class TestKernelManager(TestCase):'
70 self.assertNotIn(kid, km)
70 self.assertNotIn(kid, km)
71 # shutdown again is okay, because we have no kernels
71 # shutdown again is okay, because we have no kernels
72 km.shutdown_all()
72 km.shutdown_all()
73
73
74 def test_tcp_cinfo(self):
74 def test_tcp_cinfo(self):
75 km = self._get_tcp_km()
75 km = self._get_tcp_km()
76 self._run_cinfo(km, 'tcp', localhost())
76 self._run_cinfo(km, 'tcp', localhost())
@@ -79,9 +79,8 b' class TestKernelManager(TestCase):'
79 def test_ipc_lifecycle(self):
79 def test_ipc_lifecycle(self):
80 km = self._get_ipc_km()
80 km = self._get_ipc_km()
81 self._run_lifecycle(km)
81 self._run_lifecycle(km)
82
82
83 @dec.skip_win32
83 @dec.skip_win32
84 def test_ipc_cinfo(self):
84 def test_ipc_cinfo(self):
85 km = self._get_ipc_km()
85 km = self._get_ipc_km()
86 self._run_cinfo(km, 'ipc', 'test')
86 self._run_cinfo(km, 'ipc', 'test')
87
@@ -38,4 +38,3 b' def test_launcher():'
38 def test_connect():
38 def test_connect():
39 for name in connect.__all__:
39 for name in connect.__all__:
40 nt.assert_in(name, dir(kernel))
40 nt.assert_in(name, dir(kernel))
41
@@ -77,7 +77,7 b' class TestSession(SessionTestCase):'
77
77
78 msg = self.session.msg('execute', content=dict(a=10))
78 msg = self.session.msg('execute', content=dict(a=10))
79 self.session.send(A, msg, ident=b'foo', buffers=[b'bar'])
79 self.session.send(A, msg, ident=b'foo', buffers=[b'bar'])
80
80
81 ident, msg_list = self.session.feed_identities(B.recv_multipart())
81 ident, msg_list = self.session.feed_identities(B.recv_multipart())
82 new_msg = self.session.deserialize(msg_list)
82 new_msg = self.session.deserialize(msg_list)
83 self.assertEqual(ident[0], b'foo')
83 self.assertEqual(ident[0], b'foo')
@@ -88,7 +88,7 b' class TestSession(SessionTestCase):'
88 self.assertEqual(new_msg['parent_header'],msg['parent_header'])
88 self.assertEqual(new_msg['parent_header'],msg['parent_header'])
89 self.assertEqual(new_msg['metadata'],msg['metadata'])
89 self.assertEqual(new_msg['metadata'],msg['metadata'])
90 self.assertEqual(new_msg['buffers'],[b'bar'])
90 self.assertEqual(new_msg['buffers'],[b'bar'])
91
91
92 content = msg['content']
92 content = msg['content']
93 header = msg['header']
93 header = msg['header']
94 header['msg_id'] = self.session.msg_id
94 header['msg_id'] = self.session.msg_id
@@ -107,9 +107,9 b' class TestSession(SessionTestCase):'
107 self.assertEqual(new_msg['metadata'],msg['metadata'])
107 self.assertEqual(new_msg['metadata'],msg['metadata'])
108 self.assertEqual(new_msg['parent_header'],msg['parent_header'])
108 self.assertEqual(new_msg['parent_header'],msg['parent_header'])
109 self.assertEqual(new_msg['buffers'],[b'bar'])
109 self.assertEqual(new_msg['buffers'],[b'bar'])
110
110
111 header['msg_id'] = self.session.msg_id
111 header['msg_id'] = self.session.msg_id
112
112
113 self.session.send(A, msg, ident=b'foo', buffers=[b'bar'])
113 self.session.send(A, msg, ident=b'foo', buffers=[b'bar'])
114 ident, new_msg = self.session.recv(B)
114 ident, new_msg = self.session.recv(B)
115 self.assertEqual(ident[0], b'foo')
115 self.assertEqual(ident[0], b'foo')
@@ -216,7 +216,7 b' class TestSession(SessionTestCase):'
216 self.assertTrue(len(session.digest_history) == 100)
216 self.assertTrue(len(session.digest_history) == 100)
217 session._add_digest(uuid.uuid4().bytes)
217 session._add_digest(uuid.uuid4().bytes)
218 self.assertTrue(len(session.digest_history) == 91)
218 self.assertTrue(len(session.digest_history) == 91)
219
219
220 def test_bad_pack(self):
220 def test_bad_pack(self):
221 try:
221 try:
222 session = ss.Session(pack=_bad_packer)
222 session = ss.Session(pack=_bad_packer)
@@ -225,7 +225,7 b' class TestSession(SessionTestCase):'
225 self.assertIn("don't work", str(e))
225 self.assertIn("don't work", str(e))
226 else:
226 else:
227 self.fail("Should have raised ValueError")
227 self.fail("Should have raised ValueError")
228
228
229 def test_bad_unpack(self):
229 def test_bad_unpack(self):
230 try:
230 try:
231 session = ss.Session(unpack=_bad_unpacker)
231 session = ss.Session(unpack=_bad_unpacker)
@@ -234,7 +234,7 b' class TestSession(SessionTestCase):'
234 self.assertIn("don't work either", str(e))
234 self.assertIn("don't work either", str(e))
235 else:
235 else:
236 self.fail("Should have raised ValueError")
236 self.fail("Should have raised ValueError")
237
237
238 def test_bad_packer(self):
238 def test_bad_packer(self):
239 try:
239 try:
240 session = ss.Session(packer=__name__ + '._bad_packer')
240 session = ss.Session(packer=__name__ + '._bad_packer')
@@ -243,7 +243,7 b' class TestSession(SessionTestCase):'
243 self.assertIn("don't work", str(e))
243 self.assertIn("don't work", str(e))
244 else:
244 else:
245 self.fail("Should have raised ValueError")
245 self.fail("Should have raised ValueError")
246
246
247 def test_bad_unpacker(self):
247 def test_bad_unpacker(self):
248 try:
248 try:
249 session = ss.Session(unpacker=__name__ + '._bad_unpacker')
249 session = ss.Session(unpacker=__name__ + '._bad_unpacker')
@@ -252,11 +252,11 b' class TestSession(SessionTestCase):'
252 self.assertIn("don't work either", str(e))
252 self.assertIn("don't work either", str(e))
253 else:
253 else:
254 self.fail("Should have raised ValueError")
254 self.fail("Should have raised ValueError")
255
255
256 def test_bad_roundtrip(self):
256 def test_bad_roundtrip(self):
257 with self.assertRaises(ValueError):
257 with self.assertRaises(ValueError):
258 session = ss.Session(unpack=lambda b: 5)
258 session = ss.Session(unpack=lambda b: 5)
259
259
260 def _datetime_test(self, session):
260 def _datetime_test(self, session):
261 content = dict(t=datetime.now())
261 content = dict(t=datetime.now())
262 metadata = dict(t=datetime.now())
262 metadata = dict(t=datetime.now())
@@ -274,24 +274,24 b' class TestSession(SessionTestCase):'
274 assert isinstance(msg2['metadata']['t'], string_types)
274 assert isinstance(msg2['metadata']['t'], string_types)
275 self.assertEqual(msg['content'], jsonutil.extract_dates(msg2['content']))
275 self.assertEqual(msg['content'], jsonutil.extract_dates(msg2['content']))
276 self.assertEqual(msg['content'], jsonutil.extract_dates(msg2['content']))
276 self.assertEqual(msg['content'], jsonutil.extract_dates(msg2['content']))
277
277
278 def test_datetimes(self):
278 def test_datetimes(self):
279 self._datetime_test(self.session)
279 self._datetime_test(self.session)
280
280
281 def test_datetimes_pickle(self):
281 def test_datetimes_pickle(self):
282 session = ss.Session(packer='pickle')
282 session = ss.Session(packer='pickle')
283 self._datetime_test(session)
283 self._datetime_test(session)
284
284
285 @skipif(module_not_available('msgpack'))
285 @skipif(module_not_available('msgpack'))
286 def test_datetimes_msgpack(self):
286 def test_datetimes_msgpack(self):
287 import msgpack
287 import msgpack
288
288
289 session = ss.Session(
289 session = ss.Session(
290 pack=msgpack.packb,
290 pack=msgpack.packb,
291 unpack=lambda buf: msgpack.unpackb(buf, encoding='utf8'),
291 unpack=lambda buf: msgpack.unpackb(buf, encoding='utf8'),
292 )
292 )
293 self._datetime_test(session)
293 self._datetime_test(session)
294
294
295 def test_send_raw(self):
295 def test_send_raw(self):
296 ctx = zmq.Context.instance()
296 ctx = zmq.Context.instance()
297 A = ctx.socket(zmq.PAIR)
297 A = ctx.socket(zmq.PAIR)
@@ -300,10 +300,10 b' class TestSession(SessionTestCase):'
300 B.connect("inproc://test")
300 B.connect("inproc://test")
301
301
302 msg = self.session.msg('execute', content=dict(a=10))
302 msg = self.session.msg('execute', content=dict(a=10))
303 msg_list = [self.session.pack(msg[part]) for part in
303 msg_list = [self.session.pack(msg[part]) for part in
304 ['header', 'parent_header', 'metadata', 'content']]
304 ['header', 'parent_header', 'metadata', 'content']]
305 self.session.send_raw(A, msg_list, ident=b'foo')
305 self.session.send_raw(A, msg_list, ident=b'foo')
306
306
307 ident, new_msg_list = self.session.feed_identities(B.recv_multipart())
307 ident, new_msg_list = self.session.feed_identities(B.recv_multipart())
308 new_msg = self.session.deserialize(new_msg_list)
308 new_msg = self.session.deserialize(new_msg_list)
309 self.assertEqual(ident[0], b'foo')
309 self.assertEqual(ident[0], b'foo')
1 NO CONTENT: file renamed from IPython/kernel/threaded.py to jupyter_client/threaded.py
NO CONTENT: file renamed from IPython/kernel/threaded.py to jupyter_client/threaded.py
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now