##// END OF EJS Templates
ipy_autoreload: tune documentation a bit, and strip trailing whitespace
Pauli Virtanen -
Show More
@@ -1,7 +1,7 b''
1 1 """
2 2 IPython extension: autoreload modules before executing the next line
3 3
4 Try::
4 Try::
5 5
6 6 %autoreload?
7 7
@@ -32,7 +32,7 b' PY_COMPILED_EXT = _get_compiled_ext()'
32 32 class ModuleReloader(object):
33 33 failed = {}
34 34 """Modules that failed to reload: {module: mtime-on-failed-reload, ...}"""
35
35
36 36 modules = {}
37 37 """Modules specially marked as autoreloadable."""
38 38
@@ -44,39 +44,39 b' class ModuleReloader(object):'
44 44
45 45 old_objects = {}
46 46 """(module-name, name) -> weakref, for replacing old code objects"""
47
47
48 48 def check(self, check_all=False):
49 49 """Check whether some modules need to be reloaded."""
50
50
51 51 if check_all or self.check_all:
52 52 modules = sys.modules.keys()
53 53 else:
54 54 modules = self.modules.keys()
55
55
56 56 for modname in modules:
57 57 m = sys.modules.get(modname, None)
58 58
59 59 if modname in self.skip_modules:
60 60 continue
61
61
62 62 if not hasattr(m, '__file__'):
63 63 continue
64
64
65 65 if m.__name__ == '__main__':
66 66 # we cannot reload(__main__)
67 67 continue
68
68
69 69 filename = m.__file__
70 70 dirname = os.path.dirname(filename)
71 71 path, ext = os.path.splitext(filename)
72
72
73 73 if ext.lower() == '.py':
74 74 ext = PY_COMPILED_EXT
75 75 filename = os.path.join(dirname, path + PY_COMPILED_EXT)
76
76
77 77 if ext != PY_COMPILED_EXT:
78 78 continue
79
79
80 80 try:
81 81 pymtime = os.stat(filename[:-1]).st_mtime
82 82 if pymtime <= os.stat(filename).st_mtime:
@@ -85,7 +85,7 b' class ModuleReloader(object):'
85 85 continue
86 86 except OSError:
87 87 continue
88
88
89 89 try:
90 90 superreload(m, reload, self.old_objects)
91 91 if filename[:-1] in self.failed:
@@ -118,12 +118,12 b' def update_class(old, new):'
118 118 new_obj = getattr(new, key)
119 119 except AttributeError:
120 120 # obsolete attribute: remove it
121 try:
121 try:
122 122 delattr(old, key)
123 123 except (AttributeError, TypeError):
124 124 pass
125 125 continue
126
126
127 127 if update_generic(old_obj, new_obj): continue
128 128
129 129 try:
@@ -146,9 +146,9 b' UPDATE_RULES = ['
146 146 (lambda a, b: isinstance2(a, b, types.TypeType),
147 147 update_class),
148 148 (lambda a, b: isinstance2(a, b, types.FunctionType),
149 update_function),
149 update_function),
150 150 (lambda a, b: isinstance2(a, b, property),
151 update_property),
151 update_property),
152 152 (lambda a, b: isinstance2(a, b, types.MethodType),
153 153 lambda a, b: update_function(a.im_func, b.im_func)),
154 154 ]
@@ -168,15 +168,15 b' class StrongRef(object):'
168 168
169 169 def superreload(module, reload=reload, old_objects={}):
170 170 """Enhanced version of the builtin reload function.
171
171
172 172 superreload remembers objects previously in the module, and
173 173
174 174 - upgrades the class dictionary of every old class in the module
175 175 - upgrades the code object of every old function and method
176 176 - clears the module's namespace before reloading
177
177
178 178 """
179
179
180 180 # collect old objects in the module
181 181 for name, obj in module.__dict__.items():
182 182 if not hasattr(obj, '__module__') or obj.__module__ != module.__name__:
@@ -199,7 +199,7 b' def superreload(module, reload=reload, old_objects={}):'
199 199 except (TypeError, AttributeError, KeyError):
200 200 pass
201 201 module = reload(module)
202
202
203 203 # iterate over all objects and update functions & classes
204 204 for name, new_obj in module.__dict__.items():
205 205 key = (module.__name__, name)
@@ -248,40 +248,46 b' def disable_autoreload():'
248 248
249 249 def autoreload_f(self, parameter_s=''):
250 250 r""" %autoreload => Reload modules automatically
251
251
252 252 %autoreload
253 253 Reload all modules (except those excluded by %aimport) automatically now.
254
254
255 %autoreload 0
256 Disable automatic reloading.
257
255 258 %autoreload 1
256 259 Reload all modules imported with %aimport every time before executing
257 260 the Python code typed.
258
261
259 262 %autoreload 2
260 263 Reload all modules (except those excluded by %aimport) every time
261 264 before executing the Python code typed.
262
263 Reloading Python modules in a reliable way is in general difficult,
264 and unexpected things may occur. %autoreload tries to work
265 around common pitfalls by replacing code objects of functions
266 previously in the module with new versions. This makes the following
267 things to work:
265
266 Reloading Python modules in a reliable way is in general
267 difficult, and unexpected things may occur. %autoreload tries to
268 work around common pitfalls by replacing function code objects and
269 parts of classes previously in the module with new versions. This
270 makes the following things to work:
268 271
269 272 - Functions and classes imported via 'from xxx import foo' are upgraded
270 273 to new versions when 'xxx' is reloaded.
274
271 275 - Methods and properties of classes are upgraded on reload, so that
272 276 calling 'c.foo()' on an object 'c' created before the reload causes
273 277 the new code for 'foo' to be executed.
274
278
275 279 Some of the known remaining caveats are:
276
280
277 281 - Replacing code objects does not always succeed: changing a @property
278 282 in a class to an ordinary method or a method to a member variable
279 283 can cause problems (but in old objects only).
284
280 285 - Functions that are removed (eg. via monkey-patching) from a module
281 286 before it is reloaded are not upgraded.
287
282 288 - C extension modules cannot be reloaded, and so cannot be
283 289 autoreloaded.
284
290
285 291 """
286 292 if parameter_s == '':
287 293 reloader.check(True)
@@ -307,7 +313,7 b" def aimport_f(self, parameter_s=''):"
307 313 Mark module 'foo' to not be autoreloaded for %autoreload 1
308 314
309 315 """
310
316
311 317 modname = parameter_s
312 318 if not modname:
313 319 to_reload = reloader.modules.keys()
@@ -328,7 +334,7 b" def aimport_f(self, parameter_s=''):"
328 334 try: del reloader.skip_modules[modname]
329 335 except KeyError: pass
330 336 reloader.modules[modname] = True
331
337
332 338 # Inject module to user namespace; handle also submodules properly
333 339 __import__(modname)
334 340 basename = modname.split('.')[0]
@@ -339,5 +345,5 b' def init():'
339 345 ip.expose_magic('autoreload', autoreload_f)
340 346 ip.expose_magic('aimport', aimport_f)
341 347 ip.set_hook('pre_runcode_hook', runcode_hook)
342
348
343 349 init()
General Comments 0
You need to be logged in to leave comments. Login now