##// END OF EJS Templates
Make installation of native kernelspec explicit...
Thomas Kluyver -
Show More
@@ -100,51 +100,60 b' class KernelSpecManager(HasTraits):'
100 self.user_kernel_dir,
100 self.user_kernel_dir,
101 ]
101 ]
102
102
103 def _make_native_kernel_dir(self):
103 @property
104 def _native_kernel_dict(self):
104 """Makes a kernel directory for the native kernel.
105 """Makes a kernel directory for the native kernel.
105
106
106 The native kernel is the kernel using the same Python runtime as this
107 The native kernel is the kernel using the same Python runtime as this
107 process. This will put its informatino in the user kernels directory.
108 process. This will put its informatino in the user kernels directory.
108 """
109 """
109 path = pjoin(self.user_kernel_dir, NATIVE_KERNEL_NAME)
110 return {'argv':[sys.executable, '-c',
110 os.makedirs(path, mode=0o755)
111 'from IPython.kernel.zmq.kernelapp import main; main()',
111 with open(pjoin(path, 'kernel.json'), 'w') as f:
112 '-f', '{connection_file}'],
112 json.dump({'argv':[NATIVE_KERNEL_NAME, '-c',
113 'display_name': 'IPython (Python %d)' % (3 if PY3 else 2),
113 'from IPython.kernel.zmq.kernelapp import main; main()',
114 'language': 'python',
114 '-f', '{connection_file}'],
115 'codemirror_mode': {'name': 'ipython',
115 'display_name': 'IPython (Python %d)' % (3 if PY3 else 2),
116 'version': sys.version_info[0]},
116 'language': 'python',
117 }
117 'codemirror_mode': {'name': 'ipython',
118
118 'version': sys.version_info[0]},
119 @property
119 },
120 def _native_kernel_resource_dir(self):
120 f, indent=1)
121 # TODO: This may be different when we actually have any resources
121 # TODO: Copy icons into directory
122 return os.path.dirname(__file__)
122 return path
123
123
124 def find_kernel_specs(self):
124 def find_kernel_specs(self):
125 """Returns a dict mapping kernel names to resource directories."""
125 """Returns a dict mapping kernel names to resource directories."""
126 d = {}
126 d = {}
127 for kernel_dir in self.kernel_dirs:
127 for kernel_dir in self.kernel_dirs:
128 d.update(_list_kernels_in(kernel_dir))
128 d.update(_list_kernels_in(kernel_dir))
129
129
130 if NATIVE_KERNEL_NAME not in d:
130 d[NATIVE_KERNEL_NAME] = self._native_kernel_resource_dir
131 d[NATIVE_KERNEL_NAME] = self._make_native_kernel_dir()
132 return d
131 return d
133 # TODO: Caching?
132 # TODO: Caching?
134
133
135 def get_kernel_spec(self, kernel_name):
134 def get_kernel_spec(self, kernel_name):
136 """Returns a :class:`KernelSpec` instance for the given kernel_name.
135 """Returns a :class:`KernelSpec` instance for the given kernel_name.
137
136
138 Raises :exc:`NoSuchKernel` if the given kernel name is not found.
137 Raises :exc:`NoSuchKernel` if the given kernel name is not found.
139 """
138 """
140 if kernel_name == 'python':
139 if kernel_name in {'python', NATIVE_KERNEL_NAME}:
141 kernel_name = NATIVE_KERNEL_NAME
140 return KernelSpec(self._native_kernel_resource_dir, **self._native_kernel_dict)
141
142 d = self.find_kernel_specs()
142 d = self.find_kernel_specs()
143 try:
143 try:
144 resource_dir = d[kernel_name.lower()]
144 resource_dir = d[kernel_name.lower()]
145 except KeyError:
145 except KeyError:
146 raise NoSuchKernel(kernel_name)
146 raise NoSuchKernel(kernel_name)
147 return KernelSpec.from_resource_dir(resource_dir)
147 return KernelSpec.from_resource_dir(resource_dir)
148
149 def _get_destination_dir(self, kernel_name, system=False):
150 if system:
151 if SYSTEM_KERNEL_DIRS:
152 return os.path.join(SYSTEM_KERNEL_DIRS[-1], kernel_name)
153 else:
154 raise EnvironmentError("No system kernel directory is available")
155 else:
156 return os.path.join(self.user_kernel_dir, kernel_name)
148
157
149 def install_kernel_spec(self, source_dir, kernel_name=None, system=False,
158 def install_kernel_spec(self, source_dir, kernel_name=None, system=False,
150 replace=False):
159 replace=False):
@@ -164,20 +173,32 b' class KernelSpecManager(HasTraits):'
164 if not kernel_name:
173 if not kernel_name:
165 kernel_name = os.path.basename(source_dir)
174 kernel_name = os.path.basename(source_dir)
166 kernel_name = kernel_name.lower()
175 kernel_name = kernel_name.lower()
167
176
168 if system:
177 destination = self._get_destination_dir(kernel_name, system=system)
169 if SYSTEM_KERNEL_DIRS:
170 destination = os.path.join(SYSTEM_KERNEL_DIRS[-1], kernel_name)
171 else:
172 raise EnvironmentError("No system kernel directory is available")
173 else:
174 destination = os.path.join(self.user_kernel_dir, kernel_name)
175
178
176 if replace and os.path.isdir(destination):
179 if replace and os.path.isdir(destination):
177 shutil.rmtree(destination)
180 shutil.rmtree(destination)
178
181
179 shutil.copytree(source_dir, destination)
182 shutil.copytree(source_dir, destination)
180
183
184 def install_native_kernel_spec(self, system=False):
185 """Install the native kernel spec to the filesystem
186
187 This allows a Python 3 frontend to use a Python 2 kernel, or vice versa.
188 The kernelspec will be written pointing to the Python executable on
189 which this is run.
190
191 If ``system`` is True, it will attempt to install into the systemwide
192 kernel registry. If the process does not have appropriate permissions,
193 an :exc:`OSError` will be raised.
194 """
195 path = self._get_destination_dir(NATIVE_KERNEL_NAME, system=system)
196 os.makedirs(path, mode=0o755)
197 with open(pjoin(path, 'kernel.json'), 'w') as f:
198 json.dump(self._native_kernel_dict, f, indent=1)
199 # TODO: Copy icons into directory
200 return path
201
181 def find_kernel_specs():
202 def find_kernel_specs():
182 """Returns a dict mapping kernel names to resource directories."""
203 """Returns a dict mapping kernel names to resource directories."""
183 return KernelSpecManager().find_kernel_specs()
204 return KernelSpecManager().find_kernel_specs()
@@ -194,3 +215,8 b' def install_kernel_spec(source_dir, kernel_name=None, system=False, replace=Fals'
194 system, replace)
215 system, replace)
195
216
196 install_kernel_spec.__doc__ = KernelSpecManager.install_kernel_spec.__doc__
217 install_kernel_spec.__doc__ = KernelSpecManager.install_kernel_spec.__doc__
218
219 def install_native_kernel_spec(self, system=False):
220 return KernelSpecManager().install_native_kernel_spec(system=system)
221
222 install_native_kernel_spec.__doc__ = KernelSpecManager.install_native_kernel_spec.__doc__ No newline at end of file
@@ -91,15 +91,46 b' class InstallKernelSpec(BaseIPythonApplication):'
91 self.exit(1)
91 self.exit(1)
92 raise
92 raise
93
93
94 class InstallNativeKernelSpec(BaseIPythonApplication):
95 description = """Install the native kernel spec directory for this Python."""
96 kernel_spec_manager = Instance(KernelSpecManager)
97
98 def _kernel_spec_manager_default(self):
99 return KernelSpecManager(ipython_dir=self.ipython_dir)
100
101 system = Bool(False, config=True,
102 help="""
103 Try to install the kernel spec to the systemwide directory instead of
104 the per-user directory.
105 """
106 )
107
108 # Not all of the base aliases are meaningful (e.g. profile)
109 aliases = {k: base_aliases[k] for k in ['ipython-dir', 'log-level']}
110 flags = {'system': ({'InstallOwnKernelSpec': {'system': True}},
111 "Install to the systemwide kernel registry"),
112 'debug': base_flags['debug'],
113 }
114
115 def start(self):
116 try:
117 self.kernel_spec_manager.install_native_kernel_spec(system=self.system)
118 except OSError as e:
119 if e.errno == errno.EACCES:
120 print("Permission denied")
121 self.exit(1)
122 raise
123
94 class KernelSpecApp(Application):
124 class KernelSpecApp(Application):
95 name = "ipython kernelspec"
125 name = "ipython kernelspec"
96 description = """Manage IPython kernel specifications."""
126 description = """Manage IPython kernel specifications."""
97
127
98 subcommands = Dict(dict(
128 subcommands = Dict({
99 list = (ListKernelSpecs, ListKernelSpecs.description.splitlines()[0]),
129 'list': (ListKernelSpecs, ListKernelSpecs.description.splitlines()[0]),
100 install = (InstallKernelSpec, InstallKernelSpec.description.splitlines()[0])
130 'install': (InstallKernelSpec, InstallKernelSpec.description.splitlines()[0]),
101 ))
131 'install-self': (InstallNativeKernelSpec, InstallNativeKernelSpec.description.splitlines()[0]),
102
132 })
133
103 aliases = {}
134 aliases = {}
104 flags = {}
135 flags = {}
105
136
General Comments 0
You need to be logged in to leave comments. Login now