From 5d1a81df4213081a34576c51e7a8784263ffc270 2014-12-24 04:15:28 From: Min RK Date: 2014-12-24 04:15:28 Subject: [PATCH] Merge pull request #7203 from takluyver/kernelspecs-sys-prefix Look for kernelspecs relative to sys.prefix --- diff --git a/IPython/kernel/kernelspec.py b/IPython/kernel/kernelspec.py index 6424f34..a35d3f8 100644 --- a/IPython/kernel/kernelspec.py +++ b/IPython/kernel/kernelspec.py @@ -18,8 +18,8 @@ if os.name == 'nt': else: # PROGRAMDATA is not defined by default on XP. SYSTEM_KERNEL_DIRS = [] else: - SYSTEM_KERNEL_DIRS = ["/usr/share/ipython/kernels", - "/usr/local/share/ipython/kernels", + SYSTEM_KERNEL_DIRS = ["/usr/share/jupyter/kernels", + "/usr/local/share/jupyter/kernels", ] NATIVE_KERNEL_NAME = 'python3' if PY3 else 'python2' @@ -87,14 +87,20 @@ class KernelSpecManager(HasTraits): user_kernel_dir = Unicode() def _user_kernel_dir_default(self): return pjoin(self.ipython_dir, 'kernels') + + @property + def env_kernel_dir(self): + return pjoin(sys.prefix, 'share', 'jupyter', 'kernels') kernel_dirs = List( help="List of kernel directories to search. Later ones take priority over earlier." ) def _kernel_dirs_default(self): - return SYSTEM_KERNEL_DIRS + [ - self.user_kernel_dir, - ] + dirs = SYSTEM_KERNEL_DIRS[:] + if self.env_kernel_dir not in dirs: + dirs.append(self.env_kernel_dir) + dirs.append(self.user_kernel_dir) + return dirs @property def _native_kernel_dict(self): @@ -137,16 +143,17 @@ class KernelSpecManager(HasTraits): raise NoSuchKernel(kernel_name) return KernelSpec.from_resource_dir(resource_dir) - def _get_destination_dir(self, kernel_name, system=False): - if system: + def _get_destination_dir(self, kernel_name, user=False): + if user: + return os.path.join(self.user_kernel_dir, kernel_name) + else: if SYSTEM_KERNEL_DIRS: return os.path.join(SYSTEM_KERNEL_DIRS[-1], kernel_name) else: raise EnvironmentError("No system kernel directory is available") - else: - return os.path.join(self.user_kernel_dir, kernel_name) - def install_kernel_spec(self, source_dir, kernel_name=None, system=False, + + def install_kernel_spec(self, source_dir, kernel_name=None, user=False, replace=False): """Install a kernel spec by copying its directory. @@ -165,14 +172,14 @@ class KernelSpecManager(HasTraits): kernel_name = os.path.basename(source_dir) kernel_name = kernel_name.lower() - destination = self._get_destination_dir(kernel_name, system=system) + destination = self._get_destination_dir(kernel_name, user=user) if replace and os.path.isdir(destination): shutil.rmtree(destination) shutil.copytree(source_dir, destination) - def install_native_kernel_spec(self, system=False): + def install_native_kernel_spec(self, user=False): """Install the native kernel spec to the filesystem This allows a Python 3 frontend to use a Python 2 kernel, or vice versa. @@ -183,7 +190,7 @@ class KernelSpecManager(HasTraits): kernel registry. If the process does not have appropriate permissions, an :exc:`OSError` will be raised. """ - path = self._get_destination_dir(NATIVE_KERNEL_NAME, system=system) + path = self._get_destination_dir(NATIVE_KERNEL_NAME, user=user) os.makedirs(path, mode=0o755) with open(pjoin(path, 'kernel.json'), 'w') as f: json.dump(self._native_kernel_dict, f, indent=1) @@ -203,13 +210,13 @@ def get_kernel_spec(kernel_name): """ return KernelSpecManager().get_kernel_spec(kernel_name) -def install_kernel_spec(source_dir, kernel_name=None, system=False, replace=False): +def install_kernel_spec(source_dir, kernel_name=None, user=False, replace=False): return KernelSpecManager().install_kernel_spec(source_dir, kernel_name, - system, replace) + user, replace) install_kernel_spec.__doc__ = KernelSpecManager.install_kernel_spec.__doc__ -def install_native_kernel_spec(self, system=False): - return KernelSpecManager().install_native_kernel_spec(system=system) +def install_native_kernel_spec(user=False): + return KernelSpecManager().install_native_kernel_spec(user=user) install_native_kernel_spec.__doc__ = KernelSpecManager.install_native_kernel_spec.__doc__ diff --git a/IPython/kernel/kernelspecapp.py b/IPython/kernel/kernelspecapp.py index c1e7a45..7d966a5 100644 --- a/IPython/kernel/kernelspecapp.py +++ b/IPython/kernel/kernelspecapp.py @@ -45,10 +45,10 @@ class InstallKernelSpec(BaseIPythonApplication): def _kernel_name_default(self): return os.path.basename(self.sourcedir) - system = Bool(False, config=True, + user = Bool(False, config=True, help=""" - Try to install the kernel spec to the systemwide directory instead of - the per-user directory. + Try to install the kernel spec to the per-user directory instead of + the system or environment directory. """ ) replace = Bool(False, config=True, @@ -59,8 +59,8 @@ class InstallKernelSpec(BaseIPythonApplication): for k in ['ipython-dir', 'log-level']: aliases[k] = base_aliases[k] - flags = {'system': ({'InstallKernelSpec': {'system': True}}, - "Install to the systemwide kernel registry"), + flags = {'user': ({'InstallKernelSpec': {'user': True}}, + "Install to the per-user kernel registry"), 'replace': ({'InstallKernelSpec': {'replace': True}}, "Replace any existing kernel spec with this name."), 'debug': base_flags['debug'], @@ -79,7 +79,7 @@ class InstallKernelSpec(BaseIPythonApplication): try: self.kernel_spec_manager.install_kernel_spec(self.sourcedir, kernel_name=self.kernel_name, - system=self.system, + user=self.user, replace=self.replace, ) except OSError as e: @@ -98,23 +98,23 @@ class InstallNativeKernelSpec(BaseIPythonApplication): def _kernel_spec_manager_default(self): return KernelSpecManager(ipython_dir=self.ipython_dir) - system = Bool(False, config=True, + user = Bool(False, config=True, help=""" - Try to install the kernel spec to the systemwide directory instead of - the per-user directory. + Try to install the kernel spec to the per-user directory instead of + the system or environment directory. """ ) # Not all of the base aliases are meaningful (e.g. profile) aliases = {k: base_aliases[k] for k in ['ipython-dir', 'log-level']} - flags = {'system': ({'InstallNativeKernelSpec': {'system': True}}, - "Install to the systemwide kernel registry"), + flags = {'user': ({'InstallNativeKernelSpec': {'user': True}}, + "Install to the per-user kernel registry"), 'debug': base_flags['debug'], } def start(self): try: - self.kernel_spec_manager.install_native_kernel_spec(system=self.system) + self.kernel_spec_manager.install_native_kernel_spec(user=self.user) except OSError as e: self.exit(e) diff --git a/IPython/kernel/tests/test_kernelspec.py b/IPython/kernel/tests/test_kernelspec.py index d909784..4563699 100644 --- a/IPython/kernel/tests/test_kernelspec.py +++ b/IPython/kernel/tests/test_kernelspec.py @@ -42,21 +42,23 @@ class KernelSpecTests(unittest.TestCase): def test_install_kernel_spec(self): self.ksm.install_kernel_spec(self.installable_kernel, - kernel_name='tstinstalled') + kernel_name='tstinstalled', + user=True) self.assertIn('tstinstalled', self.ksm.find_kernel_specs()) with self.assertRaises(OSError): self.ksm.install_kernel_spec(self.installable_kernel, - kernel_name='tstinstalled') + kernel_name='tstinstalled', + user=True) # Smoketest that this succeeds self.ksm.install_kernel_spec(self.installable_kernel, kernel_name='tstinstalled', - replace=True) - + replace=True, user=True) + @onlyif(os.name != 'nt' and not os.access('/usr/local/share', os.W_OK), "needs Unix system without root privileges") def test_cant_install_kernel_spec(self): with self.assertRaises(OSError): self.ksm.install_kernel_spec(self.installable_kernel, kernel_name='tstinstalled', - system=True) + user=False)