##// END OF EJS Templates
Merge pull request #13744 from Carreau/remove-ext-loading...
Matthias Bussonnier -
r27829:1b2fc00d merge
parent child Browse files
Show More
@@ -1,167 +1,151
1 1 # encoding: utf-8
2 2 """A class for managing IPython extensions."""
3 3
4 4 # Copyright (c) IPython Development Team.
5 5 # Distributed under the terms of the Modified BSD License.
6 6
7 7 import os
8 8 import os.path
9 9 import sys
10 10 from importlib import import_module, reload
11 11
12 12 from traitlets.config.configurable import Configurable
13 13 from IPython.utils.path import ensure_dir_exists, compress_user
14 14 from IPython.utils.decorators import undoc
15 15 from traitlets import Instance
16 16
17 17
18 18 #-----------------------------------------------------------------------------
19 19 # Main class
20 20 #-----------------------------------------------------------------------------
21 21
22 22 BUILTINS_EXTS = {"storemagic": False, "autoreload": False}
23 23
24 24
25 25 class ExtensionManager(Configurable):
26 26 """A class to manage IPython extensions.
27 27
28 28 An IPython extension is an importable Python module that has
29 29 a function with the signature::
30 30
31 31 def load_ipython_extension(ipython):
32 32 # Do things with ipython
33 33
34 34 This function is called after your extension is imported and the
35 35 currently active :class:`InteractiveShell` instance is passed as
36 36 the only argument. You can do anything you want with IPython at
37 37 that point, including defining new magic and aliases, adding new
38 38 components, etc.
39 39
40 40 You can also optionally define an :func:`unload_ipython_extension(ipython)`
41 41 function, which will be called if the user unloads or reloads the extension.
42 42 The extension manager will only call :func:`load_ipython_extension` again
43 43 if the extension is reloaded.
44 44
45 45 You can put your extension modules anywhere you want, as long as
46 46 they can be imported by Python's standard import mechanism. However,
47 47 to make it easy to write extensions, you can also put your extensions
48 48 in ``os.path.join(self.ipython_dir, 'extensions')``. This directory
49 49 is added to ``sys.path`` automatically.
50 50 """
51 51
52 52 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
53 53
54 54 def __init__(self, shell=None, **kwargs):
55 55 super(ExtensionManager, self).__init__(shell=shell, **kwargs)
56 56 self.shell.observe(
57 57 self._on_ipython_dir_changed, names=('ipython_dir',)
58 58 )
59 59 self.loaded = set()
60 60
61 61 @property
62 62 def ipython_extension_dir(self):
63 63 return os.path.join(self.shell.ipython_dir, u'extensions')
64 64
65 65 def _on_ipython_dir_changed(self, change):
66 66 ensure_dir_exists(self.ipython_extension_dir)
67 67
68 68 def load_extension(self, module_str: str):
69 69 """Load an IPython extension by its module name.
70 70
71 71 Returns the string "already loaded" if the extension is already loaded,
72 72 "no load function" if the module doesn't have a load_ipython_extension
73 73 function, or None if it succeeded.
74 74 """
75 75 try:
76 76 return self._load_extension(module_str)
77 77 except ModuleNotFoundError:
78 78 if module_str in BUILTINS_EXTS:
79 79 BUILTINS_EXTS[module_str] = True
80 80 return self._load_extension("IPython.extensions." + module_str)
81 81 raise
82 82
83 83 def _load_extension(self, module_str: str):
84 84 if module_str in self.loaded:
85 85 return "already loaded"
86 86
87 87 from IPython.utils.syspathcontext import prepended_to_syspath
88 88
89 89 with self.shell.builtin_trap:
90 90 if module_str not in sys.modules:
91 with prepended_to_syspath(self.ipython_extension_dir):
92 mod = import_module(module_str)
93 if mod.__file__.startswith(self.ipython_extension_dir):
94 print(("Loading extensions from {dir} is deprecated. "
95 "We recommend managing extensions like any "
96 "other Python packages, in site-packages.").format(
97 dir=compress_user(self.ipython_extension_dir)))
91 mod = import_module(module_str)
98 92 mod = sys.modules[module_str]
99 93 if self._call_load_ipython_extension(mod):
100 94 self.loaded.add(module_str)
101 95 else:
102 96 return "no load function"
103 97
104 98 def unload_extension(self, module_str: str):
105 99 """Unload an IPython extension by its module name.
106 100
107 101 This function looks up the extension's name in ``sys.modules`` and
108 102 simply calls ``mod.unload_ipython_extension(self)``.
109 103
110 104 Returns the string "no unload function" if the extension doesn't define
111 105 a function to unload itself, "not loaded" if the extension isn't loaded,
112 106 otherwise None.
113 107 """
114 108 if BUILTINS_EXTS.get(module_str, False) is True:
115 109 module_str = "IPython.extensions." + module_str
116 110 if module_str not in self.loaded:
117 111 return "not loaded"
118 112
119 113 if module_str in sys.modules:
120 114 mod = sys.modules[module_str]
121 115 if self._call_unload_ipython_extension(mod):
122 116 self.loaded.discard(module_str)
123 117 else:
124 118 return "no unload function"
125 119
126 120 def reload_extension(self, module_str: str):
127 121 """Reload an IPython extension by calling reload.
128 122
129 123 If the module has not been loaded before,
130 124 :meth:`InteractiveShell.load_extension` is called. Otherwise
131 125 :func:`reload` is called and then the :func:`load_ipython_extension`
132 126 function of the module, if it exists is called.
133 127 """
134 128 from IPython.utils.syspathcontext import prepended_to_syspath
135 129
136 130 if BUILTINS_EXTS.get(module_str, False) is True:
137 131 module_str = "IPython.extensions." + module_str
138 132
139 133 if (module_str in self.loaded) and (module_str in sys.modules):
140 134 self.unload_extension(module_str)
141 135 mod = sys.modules[module_str]
142 136 with prepended_to_syspath(self.ipython_extension_dir):
143 137 reload(mod)
144 138 if self._call_load_ipython_extension(mod):
145 139 self.loaded.add(module_str)
146 140 else:
147 141 self.load_extension(module_str)
148 142
149 143 def _call_load_ipython_extension(self, mod):
150 144 if hasattr(mod, 'load_ipython_extension'):
151 145 mod.load_ipython_extension(self.shell)
152 146 return True
153 147
154 148 def _call_unload_ipython_extension(self, mod):
155 149 if hasattr(mod, 'unload_ipython_extension'):
156 150 mod.unload_ipython_extension(self.shell)
157 151 return True
158
159 @undoc
160 def install_extension(self, url, filename=None):
161 """
162 Deprecated.
163 """
164 # Ensure the extension directory exists
165 raise DeprecationWarning(
166 '`install_extension` and the `install_ext` magic have been deprecated since IPython 4.0'
167 'Use pip or other package managers to manage ipython extensions.')
@@ -1,103 +1,99
1 1 .. _extensions_overview:
2 2
3 3 ==================
4 4 IPython extensions
5 5 ==================
6 6
7 7 A level above configuration are IPython extensions, Python modules which modify
8 8 the behaviour of the shell. They are referred to by an importable module name,
9 and can be placed anywhere you'd normally import from, or in
10 ``.ipython/extensions/``.
9 and can be placed anywhere you'd normally import from.
11 10
12 11 Getting extensions
13 12 ==================
14 13
15 14 A few important extensions are :ref:`bundled with IPython <bundled_extensions>`.
16 15 Others can be found on the `extensions index
17 16 <https://github.com/ipython/ipython/wiki/Extensions-Index>`_ on the wiki, and
18 17 the `Framework :: IPython tag <https://pypi.python.org/pypi?:action=browse&c=586>`_
19 18 on PyPI.
20 19
21 20 Extensions on PyPI can be installed using ``pip``, like any other Python package.
22 21
23 22 Using extensions
24 23 ================
25 24
26 25 To load an extension while IPython is running, use the ``%load_ext`` magic:
27 26
28 27 .. sourcecode:: ipython
29 28
30 29 In [1]: %load_ext myextension
31 30
32 31 To load it each time IPython starts, list it in your configuration file::
33 32
34 33 c.InteractiveShellApp.extensions = [
35 34 'myextension'
36 35 ]
37 36
38 37 Writing extensions
39 38 ==================
40 39
41 40 An IPython extension is an importable Python module that has a couple of special
42 41 functions to load and unload it. Here is a template::
43 42
44 43 # myextension.py
45 44
46 45 def load_ipython_extension(ipython):
47 46 # The `ipython` argument is the currently active `InteractiveShell`
48 47 # instance, which can be used in any way. This allows you to register
49 48 # new magics or aliases, for example.
50 49
51 50 def unload_ipython_extension(ipython):
52 51 # If you want your extension to be unloadable, put that logic here.
53 52
54 53 This :func:`load_ipython_extension` function is called after your extension is
55 54 imported, and the currently active :class:`~IPython.core.interactiveshell.InteractiveShell`
56 55 instance is passed as the only argument. You can do anything you want with
57 56 IPython at that point.
58 57
59 58 :func:`load_ipython_extension` will not be called again if the user use
60 59 `%load_extension`. The user have to explicitly ask the extension to be
61 60 reloaded (with `%reload_extension`). In case where the use ask the extension to
62 61 be reloaded, , the extension will be unloaded (with
63 62 `unload_ipython_extension`), and loaded again.
64 63
65 64 Useful :class:`InteractiveShell` methods include :meth:`~IPython.core.interactiveshell.InteractiveShell.register_magic_function`,
66 65 :meth:`~IPython.core.interactiveshell.InteractiveShell.push` (to add variables to the user namespace) and
67 66 :meth:`~IPython.core.interactiveshell.InteractiveShell.drop_by_id` (to remove variables on unloading).
68 67
69 68 .. seealso::
70 69
71 70 :ref:`defining_magics`
72 71
73 72 You can put your extension modules anywhere you want, as long as they can be
74 imported by Python's standard import mechanism. However, to make it easy to
75 write extensions, you can also put your extensions in :file:`extensions/`
76 within the :ref:`IPython directory <ipythondir>`. This directory is
77 added to :data:`sys.path` automatically.
73 imported by Python's standard import mechanism.
78 74
79 75 When your extension is ready for general use, please add it to the `extensions
80 76 index <https://github.com/ipython/ipython/wiki/Extensions-Index>`_. We also
81 77 encourage you to upload it to PyPI and use the ``Framework :: IPython``
82 78 classifier, so that users can install it with standard packaging tools.
83 79
84 80 .. _bundled_extensions:
85 81
86 82 Extensions bundled with IPython
87 83 ===============================
88 84
89 85 .. toctree::
90 86 :maxdepth: 1
91 87
92 88 autoreload
93 89 storemagic
94 90
95 91 * ``octavemagic`` used to be bundled, but is now part of `oct2py <https://blink1073.github.io/oct2py/>`_.
96 92 Use ``%load_ext oct2py.ipython`` to load it.
97 93 * ``rmagic`` is now part of `rpy2 <http://rpy.sourceforge.net/>`_. Use
98 94 ``%load_ext rpy2.ipython`` to load it, and see :mod:`rpy2.ipython.rmagic` for
99 95 details of how to use it.
100 96 * ``cythonmagic`` used to be bundled, but is now part of `cython <https://github.com/cython/cython/>`_
101 97 Use ``%load_ext Cython`` to load it.
102 98 * ``sympyprinting`` used to be a bundled extension, but you should now use
103 99 :func:`sympy.init_printing` instead.
General Comments 0
You need to be logged in to leave comments. Login now