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