##// END OF EJS Templates
DOC: extensions/autoreload: better extension module docstring
Pauli Virtanen -
Show More
@@ -1,400 +1,481 b''
1 """
1 """
2 IPython extension: autoreload modules before executing the next line
2 ``autoreload`` is an IPython extension that reloads modules
3 automatically before executing the line of code typed.
3
4
4 Try::
5 This makes for example the following workflow possible:
5
6
6 %autoreload?
7 .. sourcecode:: ipython
8
9 In [1]: %load_ext autoreload
10
11 In [2]: %autoreload 2
12
13 In [3]: from foo import some_function
14
15 In [4]: some_function()
16 Out[4]: 42
17
18 In [5]: # open foo.py in an editor and change some_function to return 43
19
20 In [6]: some_function()
21 Out[6]: 43
22
23 The module was reloaded without reloading it explicitly, and the
24 object imported with ``from foo import ...`` was also updated.
25
26 Usage
27 =====
28
29 The following magic commands are provided:
30
31 ``%autoreload``
32
33 Reload all modules (except those excluded by ``%aimport``)
34 automatically now.
35
36 ``%autoreload 0``
37
38 Disable automatic reloading.
39
40 ``%autoreload 1``
41
42 Reload all modules imported with ``%aimport`` every time before
43 executing the Python code typed.
44
45 ``%autoreload 2``
46
47 Reload all modules (except those excluded by ``%aimport``) every
48 time before executing the Python code typed.
49
50 ``%aimport``
51
52 List modules which are to be automatically imported or not to be imported.
53
54 ``%aimport foo``
55
56 Import module 'foo' and mark it to be autoreloaded for ``%autoreload 1``
57
58 ``%aimport -foo``
59
60 Mark module 'foo' to not be autoreloaded.
61
62 Caveats
63 =======
64
65 Reloading Python modules in a reliable way is in general difficult,
66 and unexpected things may occur. ``%autoreload`` tries to work around
67 common pitfalls by replacing function code objects and parts of
68 classes previously in the module with new versions. This makes the
69 following things to work:
70
71 - Functions and classes imported via 'from xxx import foo' are upgraded
72 to new versions when 'xxx' is reloaded.
73
74 - Methods and properties of classes are upgraded on reload, so that
75 calling 'c.foo()' on an object 'c' created before the reload causes
76 the new code for 'foo' to be executed.
77
78 Some of the known remaining caveats are:
79
80 - Replacing code objects does not always succeed: changing a @property
81 in a class to an ordinary method or a method to a member variable
82 can cause problems (but in old objects only).
83
84 - Functions that are removed (eg. via monkey-patching) from a module
85 before it is reloaded are not upgraded.
86
87 - C extension modules cannot be reloaded, and so cannot be
88 autoreloaded.
7
89
8 for documentation.
9 """
90 """
10
91
11 # Pauli Virtanen <pav@iki.fi>, 2008.
92 # Pauli Virtanen <pav@iki.fi>, 2008.
12 # Thomas Heller, 2000.
93 # Thomas Heller, 2000.
13 #
94 #
14 # This IPython module is written by Pauli Virtanen, based on the autoreload
95 # This IPython module is written by Pauli Virtanen, based on the autoreload
15 # code by Thomas Heller.
96 # code by Thomas Heller.
16
97
17 #------------------------------------------------------------------------------
98 #------------------------------------------------------------------------------
18 # Autoreload functionality
99 # Autoreload functionality
19 #------------------------------------------------------------------------------
100 #------------------------------------------------------------------------------
20
101
21 import time, os, threading, sys, types, imp, inspect, traceback, atexit
102 import time, os, threading, sys, types, imp, inspect, traceback, atexit
22 import weakref
103 import weakref
23
104
24 def _get_compiled_ext():
105 def _get_compiled_ext():
25 """Official way to get the extension of compiled files (.pyc or .pyo)"""
106 """Official way to get the extension of compiled files (.pyc or .pyo)"""
26 for ext, mode, typ in imp.get_suffixes():
107 for ext, mode, typ in imp.get_suffixes():
27 if typ == imp.PY_COMPILED:
108 if typ == imp.PY_COMPILED:
28 return ext
109 return ext
29
110
30 PY_COMPILED_EXT = _get_compiled_ext()
111 PY_COMPILED_EXT = _get_compiled_ext()
31
112
32 class ModuleReloader(object):
113 class ModuleReloader(object):
33 enabled = False
114 enabled = False
34 """Whether this reloader is enabled"""
115 """Whether this reloader is enabled"""
35
116
36 failed = {}
117 failed = {}
37 """Modules that failed to reload: {module: mtime-on-failed-reload, ...}"""
118 """Modules that failed to reload: {module: mtime-on-failed-reload, ...}"""
38
119
39 modules = {}
120 modules = {}
40 """Modules specially marked as autoreloadable."""
121 """Modules specially marked as autoreloadable."""
41
122
42 skip_modules = {}
123 skip_modules = {}
43 """Modules specially marked as not autoreloadable."""
124 """Modules specially marked as not autoreloadable."""
44
125
45 check_all = True
126 check_all = True
46 """Autoreload all modules, not just those listed in 'modules'"""
127 """Autoreload all modules, not just those listed in 'modules'"""
47
128
48 old_objects = {}
129 old_objects = {}
49 """(module-name, name) -> weakref, for replacing old code objects"""
130 """(module-name, name) -> weakref, for replacing old code objects"""
50
131
51 def mark_module_skipped(self, module_name):
132 def mark_module_skipped(self, module_name):
52 """Skip reloading the named module in the future"""
133 """Skip reloading the named module in the future"""
53 try:
134 try:
54 del self.modules[module_name]
135 del self.modules[module_name]
55 except KeyError:
136 except KeyError:
56 pass
137 pass
57 self.skip_modules[module_name] = True
138 self.skip_modules[module_name] = True
58
139
59 def mark_module_reloadable(self, module_name):
140 def mark_module_reloadable(self, module_name):
60 """Reload the named module in the future (if it is imported)"""
141 """Reload the named module in the future (if it is imported)"""
61 try:
142 try:
62 del self.skip_modules[module_name]
143 del self.skip_modules[module_name]
63 except KeyError:
144 except KeyError:
64 pass
145 pass
65 self.modules[module_name] = True
146 self.modules[module_name] = True
66
147
67 def aimport_module(self, module_name):
148 def aimport_module(self, module_name):
68 """Import a module, and mark it reloadable
149 """Import a module, and mark it reloadable
69
150
70 Returns
151 Returns
71 -------
152 -------
72 top_module : module
153 top_module : module
73 The imported module if it is top-level, or the top-level
154 The imported module if it is top-level, or the top-level
74 top_name : module
155 top_name : module
75 Name of top_module
156 Name of top_module
76
157
77 """
158 """
78 self.mark_module_reloadable(module_name)
159 self.mark_module_reloadable(module_name)
79
160
80 __import__(module_name)
161 __import__(module_name)
81 top_name = module_name.split('.')[0]
162 top_name = module_name.split('.')[0]
82 top_module = sys.modules[top_name]
163 top_module = sys.modules[top_name]
83 return top_module, top_name
164 return top_module, top_name
84
165
85 def check(self, check_all=False):
166 def check(self, check_all=False):
86 """Check whether some modules need to be reloaded."""
167 """Check whether some modules need to be reloaded."""
87
168
88 if not self.enabled and not check_all:
169 if not self.enabled and not check_all:
89 return
170 return
90
171
91 if check_all or self.check_all:
172 if check_all or self.check_all:
92 modules = sys.modules.keys()
173 modules = sys.modules.keys()
93 else:
174 else:
94 modules = self.modules.keys()
175 modules = self.modules.keys()
95
176
96 for modname in modules:
177 for modname in modules:
97 m = sys.modules.get(modname, None)
178 m = sys.modules.get(modname, None)
98
179
99 if modname in self.skip_modules:
180 if modname in self.skip_modules:
100 continue
181 continue
101
182
102 if not hasattr(m, '__file__'):
183 if not hasattr(m, '__file__'):
103 continue
184 continue
104
185
105 if m.__name__ == '__main__':
186 if m.__name__ == '__main__':
106 # we cannot reload(__main__)
187 # we cannot reload(__main__)
107 continue
188 continue
108
189
109 filename = m.__file__
190 filename = m.__file__
110 path, ext = os.path.splitext(filename)
191 path, ext = os.path.splitext(filename)
111
192
112 if ext.lower() == '.py':
193 if ext.lower() == '.py':
113 ext = PY_COMPILED_EXT
194 ext = PY_COMPILED_EXT
114 pyc_filename = path + PY_COMPILED_EXT
195 pyc_filename = path + PY_COMPILED_EXT
115 py_filename = filename
196 py_filename = filename
116 else:
197 else:
117 pyc_filename = filename
198 pyc_filename = filename
118 py_filename = filename[:-1]
199 py_filename = filename[:-1]
119
200
120 if ext != PY_COMPILED_EXT:
201 if ext != PY_COMPILED_EXT:
121 continue
202 continue
122
203
123 try:
204 try:
124 pymtime = os.stat(py_filename).st_mtime
205 pymtime = os.stat(py_filename).st_mtime
125 if pymtime <= os.stat(pyc_filename).st_mtime:
206 if pymtime <= os.stat(pyc_filename).st_mtime:
126 continue
207 continue
127 if self.failed.get(py_filename, None) == pymtime:
208 if self.failed.get(py_filename, None) == pymtime:
128 continue
209 continue
129 except OSError:
210 except OSError:
130 continue
211 continue
131
212
132 try:
213 try:
133 superreload(m, reload, self.old_objects)
214 superreload(m, reload, self.old_objects)
134 if py_filename in self.failed:
215 if py_filename in self.failed:
135 del self.failed[py_filename]
216 del self.failed[py_filename]
136 except:
217 except:
137 print >> sys.stderr, "[autoreload of %s failed: %s]" % (
218 print >> sys.stderr, "[autoreload of %s failed: %s]" % (
138 modname, traceback.format_exc(1))
219 modname, traceback.format_exc(1))
139 self.failed[py_filename] = pymtime
220 self.failed[py_filename] = pymtime
140
221
141 #------------------------------------------------------------------------------
222 #------------------------------------------------------------------------------
142 # superreload
223 # superreload
143 #------------------------------------------------------------------------------
224 #------------------------------------------------------------------------------
144
225
145 def update_function(old, new):
226 def update_function(old, new):
146 """Upgrade the code object of a function"""
227 """Upgrade the code object of a function"""
147 for name in ['func_code', 'func_defaults', 'func_doc',
228 for name in ['func_code', 'func_defaults', 'func_doc',
148 'func_closure', 'func_globals', 'func_dict']:
229 'func_closure', 'func_globals', 'func_dict']:
149 try:
230 try:
150 setattr(old, name, getattr(new, name))
231 setattr(old, name, getattr(new, name))
151 except (AttributeError, TypeError):
232 except (AttributeError, TypeError):
152 pass
233 pass
153
234
154 def update_class(old, new):
235 def update_class(old, new):
155 """Replace stuff in the __dict__ of a class, and upgrade
236 """Replace stuff in the __dict__ of a class, and upgrade
156 method code objects"""
237 method code objects"""
157 for key in old.__dict__.keys():
238 for key in old.__dict__.keys():
158 old_obj = getattr(old, key)
239 old_obj = getattr(old, key)
159
240
160 try:
241 try:
161 new_obj = getattr(new, key)
242 new_obj = getattr(new, key)
162 except AttributeError:
243 except AttributeError:
163 # obsolete attribute: remove it
244 # obsolete attribute: remove it
164 try:
245 try:
165 delattr(old, key)
246 delattr(old, key)
166 except (AttributeError, TypeError):
247 except (AttributeError, TypeError):
167 pass
248 pass
168 continue
249 continue
169
250
170 if update_generic(old_obj, new_obj): continue
251 if update_generic(old_obj, new_obj): continue
171
252
172 try:
253 try:
173 setattr(old, key, getattr(new, key))
254 setattr(old, key, getattr(new, key))
174 except (AttributeError, TypeError):
255 except (AttributeError, TypeError):
175 pass # skip non-writable attributes
256 pass # skip non-writable attributes
176
257
177 def update_property(old, new):
258 def update_property(old, new):
178 """Replace get/set/del functions of a property"""
259 """Replace get/set/del functions of a property"""
179 update_generic(old.fdel, new.fdel)
260 update_generic(old.fdel, new.fdel)
180 update_generic(old.fget, new.fget)
261 update_generic(old.fget, new.fget)
181 update_generic(old.fset, new.fset)
262 update_generic(old.fset, new.fset)
182
263
183 def isinstance2(a, b, typ):
264 def isinstance2(a, b, typ):
184 return isinstance(a, typ) and isinstance(b, typ)
265 return isinstance(a, typ) and isinstance(b, typ)
185
266
186 UPDATE_RULES = [
267 UPDATE_RULES = [
187 (lambda a, b: isinstance2(a, b, types.ClassType),
268 (lambda a, b: isinstance2(a, b, types.ClassType),
188 update_class),
269 update_class),
189 (lambda a, b: isinstance2(a, b, types.TypeType),
270 (lambda a, b: isinstance2(a, b, types.TypeType),
190 update_class),
271 update_class),
191 (lambda a, b: isinstance2(a, b, types.FunctionType),
272 (lambda a, b: isinstance2(a, b, types.FunctionType),
192 update_function),
273 update_function),
193 (lambda a, b: isinstance2(a, b, property),
274 (lambda a, b: isinstance2(a, b, property),
194 update_property),
275 update_property),
195 (lambda a, b: isinstance2(a, b, types.MethodType),
276 (lambda a, b: isinstance2(a, b, types.MethodType),
196 lambda a, b: update_function(a.im_func, b.im_func)),
277 lambda a, b: update_function(a.im_func, b.im_func)),
197 ]
278 ]
198
279
199 def update_generic(a, b):
280 def update_generic(a, b):
200 for type_check, update in UPDATE_RULES:
281 for type_check, update in UPDATE_RULES:
201 if type_check(a, b):
282 if type_check(a, b):
202 update(a, b)
283 update(a, b)
203 return True
284 return True
204 return False
285 return False
205
286
206 class StrongRef(object):
287 class StrongRef(object):
207 def __init__(self, obj):
288 def __init__(self, obj):
208 self.obj = obj
289 self.obj = obj
209 def __call__(self):
290 def __call__(self):
210 return self.obj
291 return self.obj
211
292
212 def superreload(module, reload=reload, old_objects={}):
293 def superreload(module, reload=reload, old_objects={}):
213 """Enhanced version of the builtin reload function.
294 """Enhanced version of the builtin reload function.
214
295
215 superreload remembers objects previously in the module, and
296 superreload remembers objects previously in the module, and
216
297
217 - upgrades the class dictionary of every old class in the module
298 - upgrades the class dictionary of every old class in the module
218 - upgrades the code object of every old function and method
299 - upgrades the code object of every old function and method
219 - clears the module's namespace before reloading
300 - clears the module's namespace before reloading
220
301
221 """
302 """
222
303
223 # collect old objects in the module
304 # collect old objects in the module
224 for name, obj in module.__dict__.items():
305 for name, obj in module.__dict__.items():
225 if not hasattr(obj, '__module__') or obj.__module__ != module.__name__:
306 if not hasattr(obj, '__module__') or obj.__module__ != module.__name__:
226 continue
307 continue
227 key = (module.__name__, name)
308 key = (module.__name__, name)
228 try:
309 try:
229 old_objects.setdefault(key, []).append(weakref.ref(obj))
310 old_objects.setdefault(key, []).append(weakref.ref(obj))
230 except TypeError:
311 except TypeError:
231 # weakref doesn't work for all types;
312 # weakref doesn't work for all types;
232 # create strong references for 'important' cases
313 # create strong references for 'important' cases
233 if isinstance(obj, types.ClassType):
314 if isinstance(obj, types.ClassType):
234 old_objects.setdefault(key, []).append(StrongRef(obj))
315 old_objects.setdefault(key, []).append(StrongRef(obj))
235
316
236 # reload module
317 # reload module
237 try:
318 try:
238 # clear namespace first from old cruft
319 # clear namespace first from old cruft
239 old_dict = module.__dict__.copy()
320 old_dict = module.__dict__.copy()
240 old_name = module.__name__
321 old_name = module.__name__
241 module.__dict__.clear()
322 module.__dict__.clear()
242 module.__dict__['__name__'] = old_name
323 module.__dict__['__name__'] = old_name
243 except (TypeError, AttributeError, KeyError):
324 except (TypeError, AttributeError, KeyError):
244 pass
325 pass
245
326
246 try:
327 try:
247 module = reload(module)
328 module = reload(module)
248 except:
329 except:
249 # restore module dictionary on failed reload
330 # restore module dictionary on failed reload
250 module.__dict__.update(old_dict)
331 module.__dict__.update(old_dict)
251 raise
332 raise
252
333
253 # iterate over all objects and update functions & classes
334 # iterate over all objects and update functions & classes
254 for name, new_obj in module.__dict__.items():
335 for name, new_obj in module.__dict__.items():
255 key = (module.__name__, name)
336 key = (module.__name__, name)
256 if key not in old_objects: continue
337 if key not in old_objects: continue
257
338
258 new_refs = []
339 new_refs = []
259 for old_ref in old_objects[key]:
340 for old_ref in old_objects[key]:
260 old_obj = old_ref()
341 old_obj = old_ref()
261 if old_obj is None: continue
342 if old_obj is None: continue
262 new_refs.append(old_ref)
343 new_refs.append(old_ref)
263 update_generic(old_obj, new_obj)
344 update_generic(old_obj, new_obj)
264
345
265 if new_refs:
346 if new_refs:
266 old_objects[key] = new_refs
347 old_objects[key] = new_refs
267 else:
348 else:
268 del old_objects[key]
349 del old_objects[key]
269
350
270 return module
351 return module
271
352
272 #------------------------------------------------------------------------------
353 #------------------------------------------------------------------------------
273 # IPython connectivity
354 # IPython connectivity
274 #------------------------------------------------------------------------------
355 #------------------------------------------------------------------------------
275
356
276 from IPython.core.plugin import Plugin
357 from IPython.core.plugin import Plugin
277 from IPython.core.hooks import TryNext
358 from IPython.core.hooks import TryNext
278
359
279 class AutoreloadInterface(object):
360 class AutoreloadInterface(object):
280 def __init__(self, *a, **kw):
361 def __init__(self, *a, **kw):
281 super(AutoreloadInterface, self).__init__(*a, **kw)
362 super(AutoreloadInterface, self).__init__(*a, **kw)
282 self._reloader = ModuleReloader()
363 self._reloader = ModuleReloader()
283 self._reloader.check_all = False
364 self._reloader.check_all = False
284
365
285 def magic_autoreload(self, ipself, parameter_s=''):
366 def magic_autoreload(self, ipself, parameter_s=''):
286 r"""%autoreload => Reload modules automatically
367 r"""%autoreload => Reload modules automatically
287
368
288 %autoreload
369 %autoreload
289 Reload all modules (except those excluded by %aimport) automatically
370 Reload all modules (except those excluded by %aimport) automatically
290 now.
371 now.
291
372
292 %autoreload 0
373 %autoreload 0
293 Disable automatic reloading.
374 Disable automatic reloading.
294
375
295 %autoreload 1
376 %autoreload 1
296 Reload all modules imported with %aimport every time before executing
377 Reload all modules imported with %aimport every time before executing
297 the Python code typed.
378 the Python code typed.
298
379
299 %autoreload 2
380 %autoreload 2
300 Reload all modules (except those excluded by %aimport) every time
381 Reload all modules (except those excluded by %aimport) every time
301 before executing the Python code typed.
382 before executing the Python code typed.
302
383
303 Reloading Python modules in a reliable way is in general
384 Reloading Python modules in a reliable way is in general
304 difficult, and unexpected things may occur. %autoreload tries to
385 difficult, and unexpected things may occur. %autoreload tries to
305 work around common pitfalls by replacing function code objects and
386 work around common pitfalls by replacing function code objects and
306 parts of classes previously in the module with new versions. This
387 parts of classes previously in the module with new versions. This
307 makes the following things to work:
388 makes the following things to work:
308
389
309 - Functions and classes imported via 'from xxx import foo' are upgraded
390 - Functions and classes imported via 'from xxx import foo' are upgraded
310 to new versions when 'xxx' is reloaded.
391 to new versions when 'xxx' is reloaded.
311
392
312 - Methods and properties of classes are upgraded on reload, so that
393 - Methods and properties of classes are upgraded on reload, so that
313 calling 'c.foo()' on an object 'c' created before the reload causes
394 calling 'c.foo()' on an object 'c' created before the reload causes
314 the new code for 'foo' to be executed.
395 the new code for 'foo' to be executed.
315
396
316 Some of the known remaining caveats are:
397 Some of the known remaining caveats are:
317
398
318 - Replacing code objects does not always succeed: changing a @property
399 - Replacing code objects does not always succeed: changing a @property
319 in a class to an ordinary method or a method to a member variable
400 in a class to an ordinary method or a method to a member variable
320 can cause problems (but in old objects only).
401 can cause problems (but in old objects only).
321
402
322 - Functions that are removed (eg. via monkey-patching) from a module
403 - Functions that are removed (eg. via monkey-patching) from a module
323 before it is reloaded are not upgraded.
404 before it is reloaded are not upgraded.
324
405
325 - C extension modules cannot be reloaded, and so cannot be
406 - C extension modules cannot be reloaded, and so cannot be
326 autoreloaded.
407 autoreloaded.
327
408
328 """
409 """
329 if parameter_s == '':
410 if parameter_s == '':
330 self._reloader.check(True)
411 self._reloader.check(True)
331 elif parameter_s == '0':
412 elif parameter_s == '0':
332 self._reloader.enabled = False
413 self._reloader.enabled = False
333 elif parameter_s == '1':
414 elif parameter_s == '1':
334 self._reloader.check_all = False
415 self._reloader.check_all = False
335 self._reloader.enabled = True
416 self._reloader.enabled = True
336 elif parameter_s == '2':
417 elif parameter_s == '2':
337 self._reloader.check_all = True
418 self._reloader.check_all = True
338 self._reloader.enabled = True
419 self._reloader.enabled = True
339
420
340 def magic_aimport(self, ipself, parameter_s='', stream=None):
421 def magic_aimport(self, ipself, parameter_s='', stream=None):
341 """%aimport => Import modules for automatic reloading.
422 """%aimport => Import modules for automatic reloading.
342
423
343 %aimport
424 %aimport
344 List modules to automatically import and not to import.
425 List modules to automatically import and not to import.
345
426
346 %aimport foo
427 %aimport foo
347 Import module 'foo' and mark it to be autoreloaded for %autoreload 1
428 Import module 'foo' and mark it to be autoreloaded for %autoreload 1
348
429
349 %aimport -foo
430 %aimport -foo
350 Mark module 'foo' to not be autoreloaded for %autoreload 1
431 Mark module 'foo' to not be autoreloaded for %autoreload 1
351
432
352 """
433 """
353
434
354 modname = parameter_s
435 modname = parameter_s
355 if not modname:
436 if not modname:
356 to_reload = self._reloader.modules.keys()
437 to_reload = self._reloader.modules.keys()
357 to_reload.sort()
438 to_reload.sort()
358 to_skip = self._reloader.skip_modules.keys()
439 to_skip = self._reloader.skip_modules.keys()
359 to_skip.sort()
440 to_skip.sort()
360 if stream is None:
441 if stream is None:
361 stream = sys.stdout
442 stream = sys.stdout
362 if self._reloader.check_all:
443 if self._reloader.check_all:
363 stream.write("Modules to reload:\nall-except-skipped\n")
444 stream.write("Modules to reload:\nall-except-skipped\n")
364 else:
445 else:
365 stream.write("Modules to reload:\n%s\n" % ' '.join(to_reload))
446 stream.write("Modules to reload:\n%s\n" % ' '.join(to_reload))
366 stream.write("\nModules to skip:\n%s\n" % ' '.join(to_skip))
447 stream.write("\nModules to skip:\n%s\n" % ' '.join(to_skip))
367 elif modname.startswith('-'):
448 elif modname.startswith('-'):
368 modname = modname[1:]
449 modname = modname[1:]
369 self._reloader.mark_module_skipped(modname)
450 self._reloader.mark_module_skipped(modname)
370 else:
451 else:
371 top_module, top_name = self._reloader.aimport_module(modname)
452 top_module, top_name = self._reloader.aimport_module(modname)
372
453
373 # Inject module to user namespace
454 # Inject module to user namespace
374 ipself.push({top_name: top_module})
455 ipself.push({top_name: top_module})
375
456
376 def pre_run_code_hook(self, ipself):
457 def pre_run_code_hook(self, ipself):
377 if not self._reloader.enabled:
458 if not self._reloader.enabled:
378 raise TryNext
459 raise TryNext
379 try:
460 try:
380 self._reloader.check()
461 self._reloader.check()
381 except:
462 except:
382 pass
463 pass
383
464
384 class AutoreloadPlugin(AutoreloadInterface, Plugin):
465 class AutoreloadPlugin(AutoreloadInterface, Plugin):
385 def __init__(self, shell=None, config=None):
466 def __init__(self, shell=None, config=None):
386 super(AutoreloadPlugin, self).__init__(shell=shell, config=config)
467 super(AutoreloadPlugin, self).__init__(shell=shell, config=config)
387
468
388 self.shell.define_magic('autoreload', self.magic_autoreload)
469 self.shell.define_magic('autoreload', self.magic_autoreload)
389 self.shell.define_magic('aimport', self.magic_aimport)
470 self.shell.define_magic('aimport', self.magic_aimport)
390 self.shell.set_hook('pre_run_code_hook', self.pre_run_code_hook)
471 self.shell.set_hook('pre_run_code_hook', self.pre_run_code_hook)
391
472
392 _loaded = False
473 _loaded = False
393
474
394 def load_ipython_extension(ip):
475 def load_ipython_extension(ip):
395 """Load the extension in IPython."""
476 """Load the extension in IPython."""
396 global _loaded
477 global _loaded
397 if not _loaded:
478 if not _loaded:
398 plugin = AutoreloadPlugin(shell=ip, config=ip.config)
479 plugin = AutoreloadPlugin(shell=ip, config=ip.config)
399 ip.plugin_manager.register_plugin('autoreload', plugin)
480 ip.plugin_manager.register_plugin('autoreload', plugin)
400 _loaded = True
481 _loaded = True
General Comments 0
You need to be logged in to leave comments. Login now