##// END OF EJS Templates
Merge pull request #6945 from minrk/kernel-info-lang...
Thomas Kluyver -
r19129:1c5293bd merge
parent child Browse files
Show More
@@ -250,11 +250,9 b' define(['
250 this.events.on('kernel_ready.Kernel', function(event, data) {
250 this.events.on('kernel_ready.Kernel', function(event, data) {
251 var kinfo = data.kernel.info_reply;
251 var kinfo = data.kernel.info_reply;
252 var langinfo = kinfo.language_info || {};
252 var langinfo = kinfo.language_info || {};
253 if (!langinfo.name) langinfo.name = kinfo.language;
254
255 that.metadata.language_info = langinfo;
253 that.metadata.language_info = langinfo;
256 // Mode 'null' should be plain, unhighlighted text.
254 // Mode 'null' should be plain, unhighlighted text.
257 var cm_mode = langinfo.codemirror_mode || langinfo.language || 'null';
255 var cm_mode = langinfo.codemirror_mode || langinfo.name || 'null';
258 that.set_codemirror_mode(cm_mode);
256 that.set_codemirror_mode(cm_mode);
259 });
257 });
260
258
@@ -1861,7 +1859,7 b' define(['
1861 if (this.metadata.language_info !== undefined) {
1859 if (this.metadata.language_info !== undefined) {
1862 var langinfo = this.metadata.language_info;
1860 var langinfo = this.metadata.language_info;
1863 // Mode 'null' should be plain, unhighlighted text.
1861 // Mode 'null' should be plain, unhighlighted text.
1864 var cm_mode = langinfo.codemirror_mode || langinfo.language || 'null';
1862 var cm_mode = langinfo.codemirror_mode || langinfo.name || 'null';
1865 this.set_codemirror_mode(cm_mode);
1863 this.set_codemirror_mode(cm_mode);
1866 }
1864 }
1867
1865
@@ -102,16 +102,20 b' class V5toV4(Adapter):'
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 content = msg['content']
106 content = msg['content']
106 content.pop('banner', None)
107 for key in ('language_version', 'protocol_version'):
107 for key in ('language_version', 'protocol_version'):
108 if key in content:
108 if key in content:
109 content[key] = _version_str_to_list(content[key])
109 v4c[key] = _version_str_to_list(content[key])
110 if content.pop('implementation', '') == 'ipython' \
110 if content.get('implementation', '') == 'ipython' \
111 and 'implementation_version' in content:
111 and 'implementation_version' in content:
112 content['ipython_version'] = content.pop('implmentation_version')
112 v4c['ipython_version'] = _version_str_to_list(content['implementation_version'])
113 content.pop('implementation_version', None)
113 language_info = content.get('language_info', {})
114 content.setdefault("implmentation", content['language'])
114 language = language_info.get('name', '')
115 v4c.setdefault('language', language)
116 if 'version' in language_info:
117 v4c.setdefault('language_version', _version_str_to_list(language_info['version']))
118 msg['content'] = v4c
115 return msg
119 return msg
116
120
117 def execute_request(self, msg):
121 def execute_request(self, msg):
@@ -204,14 +208,23 b' class V4toV5(Adapter):'
204
208
205 def kernel_info_reply(self, msg):
209 def kernel_info_reply(self, msg):
206 content = msg['content']
210 content = msg['content']
207 for key in ('language_version', 'protocol_version', 'ipython_version'):
211 for key in ('protocol_version', 'ipython_version'):
208 if key in content:
212 if key in content:
209 content[key] = ".".join(map(str, content[key]))
213 content[key] = '.'.join(map(str, content[key]))
214
215 content.setdefault('protocol_version', '4.1')
210
216
211 if content['language'].startswith('python') and 'ipython_version' in content:
217 if content['language'].startswith('python') and 'ipython_version' in content:
212 content['implementation'] = 'ipython'
218 content['implementation'] = 'ipython'
213 content['implementation_version'] = content.pop('ipython_version')
219 content['implementation_version'] = content.pop('ipython_version')
214
220
221 language = content.pop('language')
222 language_info = content.setdefault('language_info', {})
223 language_info.setdefault('name', language)
224 if 'language_version' in content:
225 language_version = '.'.join(map(str, content.pop('language_version')))
226 language_info.setdefault('version', language_version)
227
215 content['banner'] = ''
228 content['banner'] = ''
216 return msg
229 return msg
217
230
@@ -169,6 +169,26 b' class V4toV5TestCase(AdapterTest):'
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):
173 msg = self.msg("kernel_info_reply", {
174 'language': 'python',
175 'language_version': [2,8,0],
176 'ipython_version': [1,2,3],
177 })
178 v4, v5 = self.adapt(msg)
179 v4c = v4['content']
180 v5c = v5['content']
181 self.assertEqual(v5c, {
182 'protocol_version': '4.1',
183 'implementation': 'ipython',
184 'implementation_version': '1.2.3',
185 'language_info': {
186 'name': 'python',
187 'version': '2.8.0',
188 },
189 'banner' : '',
190 })
191
172 # iopub channel
192 # iopub channel
173
193
174 def test_display_data(self):
194 def test_display_data(self):
@@ -305,6 +325,29 b' class V5toV4TestCase(AdapterTest):'
305 self.assertEqual(sorted(v4c), ['found', 'oname'])
325 self.assertEqual(sorted(v4c), ['found', 'oname'])
306 self.assertEqual(v4c['found'], False)
326 self.assertEqual(v4c['found'], False)
307
327
328 def test_kernel_info_reply(self):
329 msg = self.msg("kernel_info_reply", {
330 'protocol_version': '5.0',
331 'implementation': 'ipython',
332 'implementation_version': '1.2.3',
333 'language_info': {
334 'name': 'python',
335 'version': '2.8.0',
336 'mimetype': 'text/x-python',
337 },
338 'banner' : 'the banner',
339 })
340 v5, v4 = self.adapt(msg)
341 v4c = v4['content']
342 v5c = v5['content']
343 info = v5c['language_info']
344 self.assertEqual(v4c, {
345 'protocol_version': [5,0],
346 'language': 'python',
347 'language_version': [2,8,0],
348 'ipython_version': [1,2,3],
349 })
350
308 # iopub channel
351 # iopub channel
309
352
310 def test_display_data(self):
353 def test_display_data(self):
@@ -4,8 +4,8 b''
4 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
5
5
6 import re
6 import re
7 import sys
7 from distutils.version import LooseVersion as V
8 from distutils.version import LooseVersion as V
8 from subprocess import PIPE
9 try:
9 try:
10 from queue import Empty # Py 3
10 from queue import Empty # Py 3
11 except ImportError:
11 except ImportError:
@@ -13,10 +13,8 b' except ImportError:'
13
13
14 import nose.tools as nt
14 import nose.tools as nt
15
15
16 from IPython.kernel import KernelManager
17
18 from IPython.utils.traitlets import (
16 from IPython.utils.traitlets import (
19 HasTraits, TraitError, Bool, Unicode, Dict, Integer, List, Enum, Any,
17 HasTraits, TraitError, Bool, Unicode, Dict, Integer, List, Enum,
20 )
18 )
21 from IPython.utils.py3compat import string_types, iteritems
19 from IPython.utils.py3compat import string_types, iteritems
22
20
@@ -150,16 +148,21 b' class CompleteReply(Reference):'
150 cursor_end = Integer()
148 cursor_end = Integer()
151 status = Unicode()
149 status = Unicode()
152
150
151 class LanguageInfo(Reference):
152 name = Unicode('python')
153 version = Unicode(sys.version.split()[0])
153
154
154 class KernelInfoReply(Reference):
155 class KernelInfoReply(Reference):
155 protocol_version = Version(min='5.0')
156 protocol_version = Version(min='5.0')
156 implementation = Unicode('ipython')
157 implementation = Unicode('ipython')
157 implementation_version = Version(min='2.1')
158 implementation_version = Version(min='2.1')
158 language_version = Version(min='2.7')
159 language = Unicode('python')
160 language_info = Dict()
159 language_info = Dict()
161 banner = Unicode()
160 banner = Unicode()
162
161
162 def check(self, d):
163 Reference.check(self, d)
164 LanguageInfo().check(d['language_info'])
165
163
166
164 class IsCompleteReply(Reference):
167 class IsCompleteReply(Reference):
165 status = Enum((u'complete', u'incomplete', u'invalid', u'unknown'))
168 status = Enum((u'complete', u'incomplete', u'invalid', u'unknown'))
@@ -69,9 +69,10 b' class IPythonKernel(KernelBase):'
69 # Kernel info fields
69 # Kernel info fields
70 implementation = 'ipython'
70 implementation = 'ipython'
71 implementation_version = release.version
71 implementation_version = release.version
72 language = 'python'
72 language_info = {
73 language_version = sys.version.split()[0]
73 'name': 'python',
74 language_info = {'mimetype': 'text/x-python',
74 'version': sys.version.split()[0],
75 'mimetype': 'text/x-python',
75 'codemirror_mode': {'name': 'ipython',
76 'codemirror_mode': {'name': 'ipython',
76 'version': sys.version_info[0]},
77 'version': sys.version_info[0]},
77 'pygments_lexer': 'ipython%d' % (3 if PY3 else 2),
78 'pygments_lexer': 'ipython%d' % (3 if PY3 else 2),
@@ -455,8 +455,6 b' class Kernel(SingletonConfigurable):'
455 'protocol_version': release.kernel_protocol_version,
455 'protocol_version': release.kernel_protocol_version,
456 'implementation': self.implementation,
456 'implementation': self.implementation,
457 'implementation_version': self.implementation_version,
457 'implementation_version': self.implementation_version,
458 'language': self.language,
459 'language_version': self.language_version,
460 'language_info': self.language_info,
458 'language_info': self.language_info,
461 'banner': self.banner,
459 'banner': self.banner,
462 }
460 }
@@ -10,21 +10,47 b''
10 "type": "object",
10 "type": "object",
11 "additionalProperties": true,
11 "additionalProperties": true,
12 "properties": {
12 "properties": {
13 "kernel_info": {
13 "kernelspec": {
14 "description": "Kernel information.",
14 "description": "Kernel information.",
15 "type": "object",
15 "type": "object",
16 "required": ["name", "language"],
16 "required": ["name", "display_name"],
17 "properties": {
17 "properties": {
18 "name": {
18 "name": {
19 "description": "Name of the kernel specification.",
19 "description": "Name of the kernel specification.",
20 "type": "string"
20 "type": "string"
21 },
21 },
22 "language": {
22 "display_name": {
23 "description": "Name to display in UI.",
24 "type": "string"
25 }
26 }
27 },
28 "language_info": {
29 "description": "Kernel information.",
30 "type": "object",
31 "required": ["name"],
32 "properties": {
33 "name": {
23 "description": "The programming language which this kernel runs.",
34 "description": "The programming language which this kernel runs.",
24 "type": "string"
35 "type": "string"
25 },
36 },
26 "codemirror_mode": {
37 "codemirror_mode": {
27 "description": "The codemirror mode to use for code in this language.",
38 "description": "The codemirror mode to use for code in this language.",
39 "oneOf": [
40 {"type": "string"},
41 {"type": "object"}
42 ]
43 },
44 "file_extension": {
45 "description": "The file extension for files in this language.",
46 "type": "string"
47 },
48 "mimetype": {
49 "description": "The mimetype corresponding to files in this language.",
50 "type": "string"
51 },
52 "pygments_lexer": {
53 "description": "The pygments lexer to use for code in this language.",
28 "type": "string"
54 "type": "string"
29 }
55 }
30 }
56 }
@@ -722,17 +722,18 b' Message type: ``kernel_info_reply``::'
722 # (e.g. IPython.__version__ for the IPython kernel)
722 # (e.g. IPython.__version__ for the IPython kernel)
723 'implementation_version': 'X.Y.Z',
723 'implementation_version': 'X.Y.Z',
724
724
725 # Programming language in which kernel is implemented.
725 # Information about the language of code for the kernel
726 'language_info': {
727 # Name of the programming language in which kernel is implemented.
726 # Kernel included in IPython returns 'python'.
728 # Kernel included in IPython returns 'python'.
727 'language': str,
729 'name': str,
728
730
729 # Language version number.
731 # Language version number.
730 # It is Python version number (e.g., '2.7.3') for the kernel
732 # It is Python version number (e.g., '2.7.3') for the kernel
731 # included in IPython.
733 # included in IPython.
732 'language_version': 'X.Y.Z',
734 'version': 'X.Y.Z',
733
735
734 # Information about the language of code for the kernel
736 # mimetype for script files in this language
735 'language_info': {
736 'mimetype': str,
737 'mimetype': str,
737
738
738 # Extension without the dot, e.g. 'py'
739 # Extension without the dot, e.g. 'py'
@@ -779,6 +780,14 b' and `codemirror modes <http://codemirror.net/mode/index.html>`_ for those fields'
779 ``language_info``, ``implementation``, ``implementation_version``, ``banner``
780 ``language_info``, ``implementation``, ``implementation_version``, ``banner``
780 and ``help_links`` keys are added.
781 and ``help_links`` keys are added.
781
782
783 .. versionchanged:: 5.0
784
785 ``language_version`` moved to ``language_info.version``
786
787 .. versionchanged:: 5.0
788
789 ``language`` moved to ``language_info.name``
790
782 .. _msging_shutdown:
791 .. _msging_shutdown:
783
792
784 Kernel shutdown
793 Kernel shutdown
@@ -36,11 +36,15 b' At the highest level, a Jupyter notebook is a dictionary with a few keys:'
36 "metadata" : {
36 "metadata" : {
37 "signature": "hex-digest", # used for authenticating unsafe outputs on load
37 "signature": "hex-digest", # used for authenticating unsafe outputs on load
38 "kernel_info": {
38 "kernel_info": {
39 # if kernel_info is defined, its name and language fields are required.
39 # if kernel_info is defined, its name field is required.
40 "name" : "the name of the kernel",
40 "name" : "the name of the kernel"
41 "language" : "the programming language of the kernel",
42 "codemirror_mode": "The name of the codemirror mode to use [optional]"
43 },
41 },
42 "language_info": {
43 # if language_info is defined, its name field is required.
44 "name" : "the programming language of the kernel",
45 "version": "the version of the language",
46 "codemirror_mode": "The name of the codemirror mode to use [optional]"
47 }
44 },
48 },
45 "nbformat": 4,
49 "nbformat": 4,
46 "nbformat_minor": 0,
50 "nbformat_minor": 0,
General Comments 0
You need to be logged in to leave comments. Login now