##// END OF EJS Templates
Make installation of native kernelspec explicit...
Thomas Kluyver -
Show More
@@ -100,51 +100,60 b' class KernelSpecManager(HasTraits):'
100 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 105 """Makes a kernel directory for the native kernel.
105 106
106 107 The native kernel is the kernel using the same Python runtime as this
107 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 os.makedirs(path, mode=0o755)
111 with open(pjoin(path, 'kernel.json'), 'w') as f:
112 json.dump({'argv':[NATIVE_KERNEL_NAME, '-c',
113 'from IPython.kernel.zmq.kernelapp import main; main()',
114 '-f', '{connection_file}'],
115 'display_name': 'IPython (Python %d)' % (3 if PY3 else 2),
116 'language': 'python',
117 'codemirror_mode': {'name': 'ipython',
118 'version': sys.version_info[0]},
119 },
120 f, indent=1)
121 # TODO: Copy icons into directory
122 return path
123
110 return {'argv':[sys.executable, '-c',
111 'from IPython.kernel.zmq.kernelapp import main; main()',
112 '-f', '{connection_file}'],
113 'display_name': 'IPython (Python %d)' % (3 if PY3 else 2),
114 'language': 'python',
115 'codemirror_mode': {'name': 'ipython',
116 'version': sys.version_info[0]},
117 }
118
119 @property
120 def _native_kernel_resource_dir(self):
121 # TODO: This may be different when we actually have any resources
122 return os.path.dirname(__file__)
123
124 124 def find_kernel_specs(self):
125 125 """Returns a dict mapping kernel names to resource directories."""
126 126 d = {}
127 127 for kernel_dir in self.kernel_dirs:
128 128 d.update(_list_kernels_in(kernel_dir))
129
130 if NATIVE_KERNEL_NAME not in d:
131 d[NATIVE_KERNEL_NAME] = self._make_native_kernel_dir()
129
130 d[NATIVE_KERNEL_NAME] = self._native_kernel_resource_dir
132 131 return d
133 132 # TODO: Caching?
134
133
135 134 def get_kernel_spec(self, kernel_name):
136 135 """Returns a :class:`KernelSpec` instance for the given kernel_name.
137 136
138 137 Raises :exc:`NoSuchKernel` if the given kernel name is not found.
139 138 """
140 if kernel_name == 'python':
141 kernel_name = NATIVE_KERNEL_NAME
139 if kernel_name in {'python', NATIVE_KERNEL_NAME}:
140 return KernelSpec(self._native_kernel_resource_dir, **self._native_kernel_dict)
141
142 142 d = self.find_kernel_specs()
143 143 try:
144 144 resource_dir = d[kernel_name.lower()]
145 145 except KeyError:
146 146 raise NoSuchKernel(kernel_name)
147 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 158 def install_kernel_spec(self, source_dir, kernel_name=None, system=False,
150 159 replace=False):
@@ -164,20 +173,32 b' class KernelSpecManager(HasTraits):'
164 173 if not kernel_name:
165 174 kernel_name = os.path.basename(source_dir)
166 175 kernel_name = kernel_name.lower()
167
168 if 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)
176
177 destination = self._get_destination_dir(kernel_name, system=system)
175 178
176 179 if replace and os.path.isdir(destination):
177 180 shutil.rmtree(destination)
178 181
179 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 202 def find_kernel_specs():
182 203 """Returns a dict mapping kernel names to resource directories."""
183 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 215 system, replace)
195 216
196 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 91 self.exit(1)
92 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 124 class KernelSpecApp(Application):
95 125 name = "ipython kernelspec"
96 126 description = """Manage IPython kernel specifications."""
97 127
98 subcommands = Dict(dict(
99 list = (ListKernelSpecs, ListKernelSpecs.description.splitlines()[0]),
100 install = (InstallKernelSpec, InstallKernelSpec.description.splitlines()[0])
101 ))
102
128 subcommands = Dict({
129 'list': (ListKernelSpecs, ListKernelSpecs.description.splitlines()[0]),
130 'install': (InstallKernelSpec, InstallKernelSpec.description.splitlines()[0]),
131 'install-self': (InstallNativeKernelSpec, InstallNativeKernelSpec.description.splitlines()[0]),
132 })
133
103 134 aliases = {}
104 135 flags = {}
105 136
General Comments 0
You need to be logged in to leave comments. Login now