##// END OF EJS Templates
Remove old mentions and uses of ipython_extension_dir (#14310)...
M Bussonnier -
r28600:93ffc153 merge
parent child Browse files
Show More
@@ -1,150 +1,135 b''
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
14 14 from traitlets import Instance
15 15
16 16
17 17 #-----------------------------------------------------------------------------
18 18 # Main class
19 19 #-----------------------------------------------------------------------------
20 20
21 21 BUILTINS_EXTS = {"storemagic": False, "autoreload": False}
22 22
23 23
24 24 class ExtensionManager(Configurable):
25 25 """A class to manage IPython extensions.
26 26
27 27 An IPython extension is an importable Python module that has
28 28 a function with the signature::
29 29
30 30 def load_ipython_extension(ipython):
31 31 # Do things with ipython
32 32
33 33 This function is called after your extension is imported and the
34 34 currently active :class:`InteractiveShell` instance is passed as
35 35 the only argument. You can do anything you want with IPython at
36 36 that point, including defining new magic and aliases, adding new
37 37 components, etc.
38
38
39 39 You can also optionally define an :func:`unload_ipython_extension(ipython)`
40 40 function, which will be called if the user unloads or reloads the extension.
41 41 The extension manager will only call :func:`load_ipython_extension` again
42 42 if the extension is reloaded.
43 43
44 44 You can put your extension modules anywhere you want, as long as
45 they can be imported by Python's standard import mechanism. However,
46 to make it easy to write extensions, you can also put your extensions
47 in ``os.path.join(self.ipython_dir, 'extensions')``. This directory
48 is added to ``sys.path`` automatically.
45 they can be imported by Python's standard import mechanism.
49 46 """
50 47
51 48 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
52 49
53 50 def __init__(self, shell=None, **kwargs):
54 51 super(ExtensionManager, self).__init__(shell=shell, **kwargs)
55 self.shell.observe(
56 self._on_ipython_dir_changed, names=('ipython_dir',)
57 )
58 52 self.loaded = set()
59 53
60 @property
61 def ipython_extension_dir(self):
62 return os.path.join(self.shell.ipython_dir, u'extensions')
63
64 def _on_ipython_dir_changed(self, change):
65 ensure_dir_exists(self.ipython_extension_dir)
66
67 54 def load_extension(self, module_str: str):
68 55 """Load an IPython extension by its module name.
69 56
70 57 Returns the string "already loaded" if the extension is already loaded,
71 58 "no load function" if the module doesn't have a load_ipython_extension
72 59 function, or None if it succeeded.
73 60 """
74 61 try:
75 62 return self._load_extension(module_str)
76 63 except ModuleNotFoundError:
77 64 if module_str in BUILTINS_EXTS:
78 65 BUILTINS_EXTS[module_str] = True
79 66 return self._load_extension("IPython.extensions." + module_str)
80 67 raise
81 68
82 69 def _load_extension(self, module_str: str):
83 70 if module_str in self.loaded:
84 71 return "already loaded"
85 72
86 73 assert self.shell is not None
87 74
88 75 with self.shell.builtin_trap:
89 76 if module_str not in sys.modules:
90 77 mod = import_module(module_str)
91 78 mod = sys.modules[module_str]
92 79 if self._call_load_ipython_extension(mod):
93 80 self.loaded.add(module_str)
94 81 else:
95 82 return "no load function"
96 83
97 84 def unload_extension(self, module_str: str):
98 85 """Unload an IPython extension by its module name.
99 86
100 87 This function looks up the extension's name in ``sys.modules`` and
101 88 simply calls ``mod.unload_ipython_extension(self)``.
102 89
103 90 Returns the string "no unload function" if the extension doesn't define
104 91 a function to unload itself, "not loaded" if the extension isn't loaded,
105 92 otherwise None.
106 93 """
107 94 if BUILTINS_EXTS.get(module_str, False) is True:
108 95 module_str = "IPython.extensions." + module_str
109 96 if module_str not in self.loaded:
110 97 return "not loaded"
111 98
112 99 if module_str in sys.modules:
113 100 mod = sys.modules[module_str]
114 101 if self._call_unload_ipython_extension(mod):
115 102 self.loaded.discard(module_str)
116 103 else:
117 104 return "no unload function"
118 105
119 106 def reload_extension(self, module_str: str):
120 107 """Reload an IPython extension by calling reload.
121 108
122 109 If the module has not been loaded before,
123 110 :meth:`InteractiveShell.load_extension` is called. Otherwise
124 111 :func:`reload` is called and then the :func:`load_ipython_extension`
125 112 function of the module, if it exists is called.
126 113 """
127 from IPython.utils.syspathcontext import prepended_to_syspath
128 114
129 115 if BUILTINS_EXTS.get(module_str, False) is True:
130 116 module_str = "IPython.extensions." + module_str
131 117
132 118 if (module_str in self.loaded) and (module_str in sys.modules):
133 119 self.unload_extension(module_str)
134 120 mod = sys.modules[module_str]
135 with prepended_to_syspath(self.ipython_extension_dir):
136 reload(mod)
121 reload(mod)
137 122 if self._call_load_ipython_extension(mod):
138 123 self.loaded.add(module_str)
139 124 else:
140 125 self.load_extension(module_str)
141 126
142 127 def _call_load_ipython_extension(self, mod):
143 128 if hasattr(mod, 'load_ipython_extension'):
144 129 mod.load_ipython_extension(self.shell)
145 130 return True
146 131
147 132 def _call_unload_ipython_extension(self, mod):
148 133 if hasattr(mod, 'unload_ipython_extension'):
149 134 mod.unload_ipython_extension(self.shell)
150 135 return True
General Comments 0
You need to be logged in to leave comments. Login now