##// END OF EJS Templates
Fixes #11068 : Cleanup extra logic that handle python <=3.3 in IPython/core/extensions.py
Subhendu Ranjan Mishra -
Show More
@@ -1,155 +1,150 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """A class for managing IPython extensions."""
2 """A class for managing IPython extensions."""
3
3
4 # Copyright (c) IPython Development Team.
4 # Copyright (c) IPython Development Team.
5 # Distributed under the terms of the Modified BSD License.
5 # Distributed under the terms of the Modified BSD License.
6
6
7 import os
7 import os
8 import os.path
8 import os.path
9 import sys
9 import sys
10 from importlib import import_module
10 from importlib import import_module, reload
11
11
12 from traitlets.config.configurable import Configurable
12 from traitlets.config.configurable import Configurable
13 from IPython.utils.path import ensure_dir_exists, compress_user
13 from IPython.utils.path import ensure_dir_exists, compress_user
14 from IPython.utils.decorators import undoc
14 from IPython.utils.decorators import undoc
15 from traitlets import Instance
15 from traitlets import Instance
16
16
17 try:
18 from importlib import reload
19 except ImportError :
20 ## deprecated since 3.4
21 from imp import reload
22
17
23 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
24 # Main class
19 # Main class
25 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
26
21
27 class ExtensionManager(Configurable):
22 class ExtensionManager(Configurable):
28 """A class to manage IPython extensions.
23 """A class to manage IPython extensions.
29
24
30 An IPython extension is an importable Python module that has
25 An IPython extension is an importable Python module that has
31 a function with the signature::
26 a function with the signature::
32
27
33 def load_ipython_extension(ipython):
28 def load_ipython_extension(ipython):
34 # Do things with ipython
29 # Do things with ipython
35
30
36 This function is called after your extension is imported and the
31 This function is called after your extension is imported and the
37 currently active :class:`InteractiveShell` instance is passed as
32 currently active :class:`InteractiveShell` instance is passed as
38 the only argument. You can do anything you want with IPython at
33 the only argument. You can do anything you want with IPython at
39 that point, including defining new magic and aliases, adding new
34 that point, including defining new magic and aliases, adding new
40 components, etc.
35 components, etc.
41
36
42 You can also optionally define an :func:`unload_ipython_extension(ipython)`
37 You can also optionally define an :func:`unload_ipython_extension(ipython)`
43 function, which will be called if the user unloads or reloads the extension.
38 function, which will be called if the user unloads or reloads the extension.
44 The extension manager will only call :func:`load_ipython_extension` again
39 The extension manager will only call :func:`load_ipython_extension` again
45 if the extension is reloaded.
40 if the extension is reloaded.
46
41
47 You can put your extension modules anywhere you want, as long as
42 You can put your extension modules anywhere you want, as long as
48 they can be imported by Python's standard import mechanism. However,
43 they can be imported by Python's standard import mechanism. However,
49 to make it easy to write extensions, you can also put your extensions
44 to make it easy to write extensions, you can also put your extensions
50 in ``os.path.join(self.ipython_dir, 'extensions')``. This directory
45 in ``os.path.join(self.ipython_dir, 'extensions')``. This directory
51 is added to ``sys.path`` automatically.
46 is added to ``sys.path`` automatically.
52 """
47 """
53
48
54 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
49 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
55
50
56 def __init__(self, shell=None, **kwargs):
51 def __init__(self, shell=None, **kwargs):
57 super(ExtensionManager, self).__init__(shell=shell, **kwargs)
52 super(ExtensionManager, self).__init__(shell=shell, **kwargs)
58 self.shell.observe(
53 self.shell.observe(
59 self._on_ipython_dir_changed, names=('ipython_dir',)
54 self._on_ipython_dir_changed, names=('ipython_dir',)
60 )
55 )
61 self.loaded = set()
56 self.loaded = set()
62
57
63 @property
58 @property
64 def ipython_extension_dir(self):
59 def ipython_extension_dir(self):
65 return os.path.join(self.shell.ipython_dir, u'extensions')
60 return os.path.join(self.shell.ipython_dir, u'extensions')
66
61
67 def _on_ipython_dir_changed(self, change):
62 def _on_ipython_dir_changed(self, change):
68 ensure_dir_exists(self.ipython_extension_dir)
63 ensure_dir_exists(self.ipython_extension_dir)
69
64
70 def load_extension(self, module_str):
65 def load_extension(self, module_str):
71 """Load an IPython extension by its module name.
66 """Load an IPython extension by its module name.
72
67
73 Returns the string "already loaded" if the extension is already loaded,
68 Returns the string "already loaded" if the extension is already loaded,
74 "no load function" if the module doesn't have a load_ipython_extension
69 "no load function" if the module doesn't have a load_ipython_extension
75 function, or None if it succeeded.
70 function, or None if it succeeded.
76 """
71 """
77 if module_str in self.loaded:
72 if module_str in self.loaded:
78 return "already loaded"
73 return "already loaded"
79
74
80 from IPython.utils.syspathcontext import prepended_to_syspath
75 from IPython.utils.syspathcontext import prepended_to_syspath
81
76
82 with self.shell.builtin_trap:
77 with self.shell.builtin_trap:
83 if module_str not in sys.modules:
78 if module_str not in sys.modules:
84 with prepended_to_syspath(self.ipython_extension_dir):
79 with prepended_to_syspath(self.ipython_extension_dir):
85 mod = import_module(module_str)
80 mod = import_module(module_str)
86 if mod.__file__.startswith(self.ipython_extension_dir):
81 if mod.__file__.startswith(self.ipython_extension_dir):
87 print(("Loading extensions from {dir} is deprecated. "
82 print(("Loading extensions from {dir} is deprecated. "
88 "We recommend managing extensions like any "
83 "We recommend managing extensions like any "
89 "other Python packages, in site-packages.").format(
84 "other Python packages, in site-packages.").format(
90 dir=compress_user(self.ipython_extension_dir)))
85 dir=compress_user(self.ipython_extension_dir)))
91 mod = sys.modules[module_str]
86 mod = sys.modules[module_str]
92 if self._call_load_ipython_extension(mod):
87 if self._call_load_ipython_extension(mod):
93 self.loaded.add(module_str)
88 self.loaded.add(module_str)
94 else:
89 else:
95 return "no load function"
90 return "no load function"
96
91
97 def unload_extension(self, module_str):
92 def unload_extension(self, module_str):
98 """Unload an IPython extension by its module name.
93 """Unload an IPython extension by its module name.
99
94
100 This function looks up the extension's name in ``sys.modules`` and
95 This function looks up the extension's name in ``sys.modules`` and
101 simply calls ``mod.unload_ipython_extension(self)``.
96 simply calls ``mod.unload_ipython_extension(self)``.
102
97
103 Returns the string "no unload function" if the extension doesn't define
98 Returns the string "no unload function" if the extension doesn't define
104 a function to unload itself, "not loaded" if the extension isn't loaded,
99 a function to unload itself, "not loaded" if the extension isn't loaded,
105 otherwise None.
100 otherwise None.
106 """
101 """
107 if module_str not in self.loaded:
102 if module_str not in self.loaded:
108 return "not loaded"
103 return "not loaded"
109
104
110 if module_str in sys.modules:
105 if module_str in sys.modules:
111 mod = sys.modules[module_str]
106 mod = sys.modules[module_str]
112 if self._call_unload_ipython_extension(mod):
107 if self._call_unload_ipython_extension(mod):
113 self.loaded.discard(module_str)
108 self.loaded.discard(module_str)
114 else:
109 else:
115 return "no unload function"
110 return "no unload function"
116
111
117 def reload_extension(self, module_str):
112 def reload_extension(self, module_str):
118 """Reload an IPython extension by calling reload.
113 """Reload an IPython extension by calling reload.
119
114
120 If the module has not been loaded before,
115 If the module has not been loaded before,
121 :meth:`InteractiveShell.load_extension` is called. Otherwise
116 :meth:`InteractiveShell.load_extension` is called. Otherwise
122 :func:`reload` is called and then the :func:`load_ipython_extension`
117 :func:`reload` is called and then the :func:`load_ipython_extension`
123 function of the module, if it exists is called.
118 function of the module, if it exists is called.
124 """
119 """
125 from IPython.utils.syspathcontext import prepended_to_syspath
120 from IPython.utils.syspathcontext import prepended_to_syspath
126
121
127 if (module_str in self.loaded) and (module_str in sys.modules):
122 if (module_str in self.loaded) and (module_str in sys.modules):
128 self.unload_extension(module_str)
123 self.unload_extension(module_str)
129 mod = sys.modules[module_str]
124 mod = sys.modules[module_str]
130 with prepended_to_syspath(self.ipython_extension_dir):
125 with prepended_to_syspath(self.ipython_extension_dir):
131 reload(mod)
126 reload(mod)
132 if self._call_load_ipython_extension(mod):
127 if self._call_load_ipython_extension(mod):
133 self.loaded.add(module_str)
128 self.loaded.add(module_str)
134 else:
129 else:
135 self.load_extension(module_str)
130 self.load_extension(module_str)
136
131
137 def _call_load_ipython_extension(self, mod):
132 def _call_load_ipython_extension(self, mod):
138 if hasattr(mod, 'load_ipython_extension'):
133 if hasattr(mod, 'load_ipython_extension'):
139 mod.load_ipython_extension(self.shell)
134 mod.load_ipython_extension(self.shell)
140 return True
135 return True
141
136
142 def _call_unload_ipython_extension(self, mod):
137 def _call_unload_ipython_extension(self, mod):
143 if hasattr(mod, 'unload_ipython_extension'):
138 if hasattr(mod, 'unload_ipython_extension'):
144 mod.unload_ipython_extension(self.shell)
139 mod.unload_ipython_extension(self.shell)
145 return True
140 return True
146
141
147 @undoc
142 @undoc
148 def install_extension(self, url, filename=None):
143 def install_extension(self, url, filename=None):
149 """
144 """
150 Deprecated.
145 Deprecated.
151 """
146 """
152 # Ensure the extension directory exists
147 # Ensure the extension directory exists
153 raise DeprecationWarning(
148 raise DeprecationWarning(
154 '`install_extension` and the `install_ext` magic have been deprecated since IPython 4.0'
149 '`install_extension` and the `install_ext` magic have been deprecated since IPython 4.0'
155 'Use pip or other package managers to manage ipython extensions.')
150 'Use pip or other package managers to manage ipython extensions.')
General Comments 0
You need to be logged in to leave comments. Login now