extensions.py
123 lines
| 4.6 KiB
| text/x-python
|
PythonLexer
Brian Granger
|
r2731 | # encoding: utf-8 | |
"""A class for managing IPython extensions. | |||
Authors: | |||
* Brian Granger | |||
""" | |||
#----------------------------------------------------------------------------- | |||
# Copyright (C) 2010 The IPython Development Team | |||
# | |||
# Distributed under the terms of the BSD License. The full license is in | |||
# the file COPYING, distributed as part of this software. | |||
#----------------------------------------------------------------------------- | |||
#----------------------------------------------------------------------------- | |||
# Imports | |||
#----------------------------------------------------------------------------- | |||
import os | |||
import sys | |||
from IPython.config.configurable import Configurable | |||
from IPython.utils.traitlets import Instance | |||
#----------------------------------------------------------------------------- | |||
# Main class | |||
#----------------------------------------------------------------------------- | |||
class ExtensionManager(Configurable): | |||
shell = Instance('IPython.core.iplib.InteractiveShell') | |||
def __init__(self, shell, config=None): | |||
super(ExtensionManager, self).__init__(config=config) | |||
self.shell = shell | |||
self.shell.on_trait_change( | |||
self._on_ipython_dir_changed, 'ipython_dir' | |||
) | |||
def __del__(self): | |||
self.shell.on_trait_change( | |||
self._on_ipython_dir_changed, 'ipython_dir', remove=True | |||
) | |||
@property | |||
def ipython_extension_dir(self): | |||
return os.path.join(self.shell.ipython_dir, u'extensions') | |||
def _on_ipython_dir_changed(self): | |||
if not os.path.isdir(self.ipython_extension_dir): | |||
os.makedirs(self.ipython_extension_dir, mode = 0777) | |||
def load_extension(self, module_str): | |||
"""Load an IPython extension by its module name. | |||
An IPython extension is an importable Python module that has | |||
a function with the signature:: | |||
def load_ipython_extension(ipython): | |||
# Do things with ipython | |||
This function is called after your extension is imported and the | |||
currently active :class:`InteractiveShell` instance is passed as | |||
the only argument. You can do anything you want with IPython at | |||
that point, including defining new magic and aliases, adding new | |||
components, etc. | |||
The :func:`load_ipython_extension` will be called again is you | |||
load or reload the extension again. It is up to the extension | |||
author to add code to manage that. | |||
You can put your extension modules anywhere you want, as long as | |||
they can be imported by Python's standard import mechanism. However, | |||
to make it easy to write extensions, you can also put your extensions | |||
in ``os.path.join(self.ipython_dir, 'extensions')``. This directory | |||
is added to ``sys.path`` automatically. | |||
If :func:`load_ipython_extension` returns anything, this function | |||
will return that object. | |||
""" | |||
from IPython.utils.syspathcontext import prepended_to_syspath | |||
if module_str not in sys.modules: | |||
with prepended_to_syspath(self.ipython_extension_dir): | |||
__import__(module_str) | |||
mod = sys.modules[module_str] | |||
return self._call_load_ipython_extension(mod) | |||
def unload_extension(self, module_str): | |||
"""Unload an IPython extension by its module name. | |||
This function looks up the extension's name in ``sys.modules`` and | |||
simply calls ``mod.unload_ipython_extension(self)``. | |||
""" | |||
if module_str in sys.modules: | |||
mod = sys.modules[module_str] | |||
self._call_unload_ipython_extension(mod) | |||
def reload_extension(self, module_str): | |||
"""Reload an IPython extension by calling reload. | |||
If the module has not been loaded before, | |||
:meth:`InteractiveShell.load_extension` is called. Otherwise | |||
:func:`reload` is called and then the :func:`load_ipython_extension` | |||
function of the module, if it exists is called. | |||
""" | |||
from IPython.utils.syspathcontext import prepended_to_syspath | |||
with prepended_to_syspath(self.ipython_extension_dir): | |||
if module_str in sys.modules: | |||
mod = sys.modules[module_str] | |||
reload(mod) | |||
self._call_load_ipython_extension(mod) | |||
else: | |||
self.load_extension(module_str) | |||
def _call_load_ipython_extension(self, mod): | |||
if hasattr(mod, 'load_ipython_extension'): | |||
return mod.load_ipython_extension(self.shell) | |||
def _call_unload_ipython_extension(self, mod): | |||
if hasattr(mod, 'unload_ipython_extension'): | |||
return mod.unload_ipython_extension(self.shell) |