Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 437 lines (322 sloc) 15.225 kb
cb48c22 Fabio Zadrozny Fixing line endings.
authored
1 """
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
2 Based on the python xreload.
3
17803f0 Fabio Zadrozny Docs
authored
4 Changes
5 ======================
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
6
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
7 1. we don't recreate the old namespace from new classes. Rather, we keep the existing namespace,
8 load a new version of it and update only some of the things we can inplace. That way, we don't break
9 things such as singletons or end up with a second representation of the same class in memory.
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
10
11 2. If we find it to be a __metaclass__, we try to update it as a regular class.
12
13 3. We don't remove old attributes (and leave them lying around even if they're no longer used).
14
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
15 4. Reload hooks were changed
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
16
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
17 These changes make it more stable, especially in the common case (where in a debug session only the
17803f0 Fabio Zadrozny Docs
authored
18 contents of a function are changed), besides providing flexibility for users that want to extend
19 on it.
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
20
21
17803f0 Fabio Zadrozny Docs
authored
22
23 Hooks
24 ======================
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
25
26 Classes/modules can be specially crafted to work with the reload (so that it can, for instance,
27 update some constant which was changed).
28
17803f0 Fabio Zadrozny Docs
authored
29
30 1. To participate in the change of some attribute:
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
31
32 In a module:
33
34 __xreload_old_new__(namespace, name, old, new)
35
36 in a class:
37
38 @classmethod
39 __xreload_old_new__(cls, name, old, new)
40
41 A class or module may include a method called '__xreload_old_new__' which is called when we're
42 unable to reload a given attribute.
43
44
45
17803f0 Fabio Zadrozny Docs
authored
46 2. To do something after the whole reload is finished:
47
48 In a module:
49
50 __xreload_after_reload_update__(namespace):
51
52 In a class:
53
54 @classmethod
55 __xreload_after_reload_update__(cls):
56
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
57
58 A class or module may include a method called '__xreload_after_reload_update__' which is called
59 after the reload finishes.
60
7eb4070 Fabio Zadrozny Improving reload code a bit to deal with Kivy Widget based classes (i.e....
authored
61
17803f0 Fabio Zadrozny Docs
authored
62 Current limitations
63 ======================
7eb4070 Fabio Zadrozny Improving reload code a bit to deal with Kivy Widget based classes (i.e....
authored
64
65
17803f0 Fabio Zadrozny Docs
authored
66 - Attributes/constants are added, but not changed (so singletons and the application state is not
67 broken -- use provided hooks to workaround it).
68
69 - Code using metaclasses may not always work.
70
71 - Functions and methods using decorators (other than classmethod and staticmethod) are not handled
72 correctly.
73
74 - Renamings are not handled correctly.
cb48c22 Fabio Zadrozny Fixing line endings.
authored
75
17803f0 Fabio Zadrozny Docs
authored
76 - Dependent modules are not reloaded.
cb48c22 Fabio Zadrozny Fixing line endings.
authored
77
17803f0 Fabio Zadrozny Docs
authored
78 - New __slots__ can't be added to existing classes.
cb48c22 Fabio Zadrozny Fixing line endings.
authored
79
80
17803f0 Fabio Zadrozny Docs
authored
81 Info
82 ======================
cb48c22 Fabio Zadrozny Fixing line endings.
authored
83
17803f0 Fabio Zadrozny Docs
authored
84 Original: http://svn.python.org/projects/sandbox/trunk/xreload/xreload.py
85 Note: it seems https://github.com/plone/plone.reload/blob/master/plone/reload/xreload.py enhances it (to check later)
cb48c22 Fabio Zadrozny Fixing line endings.
authored
86
17803f0 Fabio Zadrozny Docs
authored
87 Interesting alternative: https://code.google.com/p/reimport/
88
89 Alternative to reload().
cb48c22 Fabio Zadrozny Fixing line endings.
authored
90
17803f0 Fabio Zadrozny Docs
authored
91 This works by executing the module in a scratch namespace, and then patching classes, methods and
92 functions in place. This avoids the need to patch instances. New objects are copied into the
93 target namespace.
cb48c22 Fabio Zadrozny Fixing line endings.
authored
94
95 """
96
97 import imp
cbefd1a Fabio Zadrozny Live coding on debugger.
authored
98 from pydev_imports import Exec
54138d5 Fabio Zadrozny Added a way to skip functions with #@DontTrace. For now must be enabled ...
authored
99 import pydevd_dont_trace
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
100 import sys
101 import traceback
102 import types
7eb4070 Fabio Zadrozny Improving reload code a bit to deal with Kivy Widget based classes (i.e....
authored
103
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
104 NO_DEBUG = 0
105 LEVEL1 = 1
106 LEVEL2 = 2
7eb4070 Fabio Zadrozny Improving reload code a bit to deal with Kivy Widget based classes (i.e....
authored
107
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
108 DEBUG = NO_DEBUG
109
110 def write(*args):
111 new_lst = []
112 for a in args:
113 new_lst.append(str(a))
114
115 msg = ' '.join(new_lst)
116 sys.stdout.write('%s\n' % (msg,))
117
118 def write_err(*args):
119 new_lst = []
120 for a in args:
121 new_lst.append(str(a))
7eb4070 Fabio Zadrozny Improving reload code a bit to deal with Kivy Widget based classes (i.e....
authored
122
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
123 msg = ' '.join(new_lst)
124 sys.stderr.write('pydev debugger: %s\n' % (msg,))
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
125
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
126 def notify_info0(*args):
127 write_err(*args)
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
128
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
129 def notify_info(*args):
130 if DEBUG >= LEVEL1:
131 write(*args)
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
132
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
133 def notify_info2(*args):
134 if DEBUG >= LEVEL2:
135 write(*args)
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
136
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
137 def notify_error(*args):
138 write_err(*args)
7eb4070 Fabio Zadrozny Improving reload code a bit to deal with Kivy Widget based classes (i.e....
authored
139
140
141
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
142 #=======================================================================================================================
143 # code_objects_equal
144 #=======================================================================================================================
7eb4070 Fabio Zadrozny Improving reload code a bit to deal with Kivy Widget based classes (i.e....
authored
145 def code_objects_equal(code0, code1):
146 for d in dir(code0):
147 if d.startswith('_') or 'lineno' in d:
148 continue
149 if getattr(code0, d) != getattr(code1, d):
150 return False
151 return True
cb48c22 Fabio Zadrozny Fixing line endings.
authored
152
153
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
154 #=======================================================================================================================
155 # xreload
156 #=======================================================================================================================
cb48c22 Fabio Zadrozny Fixing line endings.
authored
157 def xreload(mod):
158 """Reload a module in place, updating classes, methods and functions.
159
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
160 mod: a module object
cb48c22 Fabio Zadrozny Fixing line endings.
authored
161 """
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
162 r = Reload(mod)
163 r.apply()
164 r = None
54138d5 Fabio Zadrozny Added a way to skip functions with #@DontTrace. For now must be enabled ...
authored
165 pydevd_dont_trace.clear_trace_filter_cache()
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
166
167
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
168 # This isn't actually used... Initially I planned to reload variables which are immutable on the
169 # namespace, but this can destroy places where we're saving state, which may not be what we want,
170 # so, we're being conservative and giving the user hooks if he wants to do a reload.
171 #
172 # immutable_types = [int, str, float, tuple] #That should be common to all Python versions
173 #
174 # for name in 'long basestr unicode frozenset'.split():
175 # try:
176 # immutable_types.append(__builtins__[name])
177 # except:
178 # pass #Just ignore: not all python versions are created equal.
179 # immutable_types = tuple(immutable_types)
180
181
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
182 #=======================================================================================================================
183 # Reload
184 #=======================================================================================================================
185 class Reload:
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
186
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
187 def __init__(self, mod):
188 self.mod = mod
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
189
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
190 def apply(self):
191 mod = self.mod
192 self._on_finish_callbacks = []
7eb4070 Fabio Zadrozny Improving reload code a bit to deal with Kivy Widget based classes (i.e....
authored
193 try:
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
194 # Get the module name, e.g. 'foo.bar.whatever'
195 modname = mod.__name__
196 # Get the module namespace (dict) early; this is part of the type check
197 modns = mod.__dict__
198 # Parse it into package name and module name, e.g. 'foo.bar' and 'whatever'
199 i = modname.rfind(".")
200 if i >= 0:
201 pkgname, modname = modname[:i], modname[i + 1:]
7eb4070 Fabio Zadrozny Improving reload code a bit to deal with Kivy Widget based classes (i.e....
authored
202 else:
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
203 pkgname = None
204 # Compute the search path
205 if pkgname:
206 # We're not reloading the package, only the module in it
207 pkg = sys.modules[pkgname]
208 path = pkg.__path__ # Search inside the package
209 else:
210 # Search the top-level module path
211 pkg = None
212 path = None # Make find_module() uses the default search path
213 # Find the module; may raise ImportError
214 (stream, filename, (suffix, mode, kind)) = imp.find_module(modname, path)
215 # Turn it into a code object
216 try:
217 # Is it Python source code or byte code read from a file?
218 if kind not in (imp.PY_COMPILED, imp.PY_SOURCE):
219 # Fall back to built-in reload()
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
220 notify_error('Could not find source to reload (mod: %s)' % (modname,))
221 return
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
222 if kind == imp.PY_SOURCE:
223 source = stream.read()
224 code = compile(source, filename, "exec")
225 else:
226 import marshal
227 code = marshal.load(stream)
228 finally:
229 if stream:
230 stream.close()
231 # Execute the code. We copy the module dict to a temporary; then
232 # clear the module dict; then execute the new code in the module
233 # dict; then swap things back and around. This trick (due to
234 # Glyph Lefkowitz) ensures that the (readonly) __globals__
235 # attribute of methods and functions is set to the correct dict
236 # object.
237 new_namespace = modns.copy()
238 new_namespace.clear()
239 new_namespace["__name__"] = modns["__name__"]
240 Exec(code, new_namespace)
241 # Now we get to the hard part
242 oldnames = set(modns)
243 newnames = set(new_namespace)
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
244
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
245 # Create new tokens (note: not deleting existing)
246 for name in newnames - oldnames:
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
247 notify_info0('Added:', name, 'to namespace')
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
248 modns[name] = new_namespace[name]
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
249
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
250 # Update in-place what we can
251 for name in oldnames & newnames:
252 self._update(modns, name, modns[name], new_namespace[name])
253
254 self._handle_namespace(modns)
255
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
256 for c in self._on_finish_callbacks:
257 c()
258 del self._on_finish_callbacks[:]
259 except:
260 traceback.print_exc()
261
262
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
263 def _handle_namespace(self, namespace, is_class_namespace=False):
264 on_finish = None
265 if is_class_namespace:
266 xreload_after_update = getattr(namespace, '__xreload_after_reload_update__', None)
267 if xreload_after_update is not None:
268 on_finish = lambda: xreload_after_update()
269
270 elif '__xreload_after_reload_update__' in namespace:
271 xreload_after_update = namespace['__xreload_after_reload_update__']
272 on_finish = lambda: xreload_after_update(namespace)
273
274
275 if on_finish is not None:
276 # If a client wants to know about it, give him a chance.
277 self._on_finish_callbacks.append(on_finish)
278
279
280
281 def _update(self, namespace, name, oldobj, newobj, is_class_namespace=False):
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
282 """Update oldobj, if possible in place, with newobj.
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
283
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
284 If oldobj is immutable, this simply returns newobj.
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
285
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
286 Args:
287 oldobj: the object to be updated
288 newobj: the object used as the source for the update
289 """
4e1679f Fabio Zadrozny Improving pydevd_reload.
authored
290 try:
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
291 notify_info2('Updating: ', oldobj)
4e1679f Fabio Zadrozny Improving pydevd_reload.
authored
292 if oldobj is newobj:
293 # Probably something imported
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
294 return
295
4e1679f Fabio Zadrozny Improving pydevd_reload.
authored
296 if type(oldobj) is not type(newobj):
297 # Cop-out: if the type changed, give up
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
298 notify_error('Type of: %s changed... Skipping.' % (oldobj,))
299 return
300
4e1679f Fabio Zadrozny Improving pydevd_reload.
authored
301 if isinstance(newobj, types.FunctionType):
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
302 self._update_function(oldobj, newobj)
303 return
304
4e1679f Fabio Zadrozny Improving pydevd_reload.
authored
305 if isinstance(newobj, types.MethodType):
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
306 self._update_method(oldobj, newobj)
307 return
308
4e1679f Fabio Zadrozny Improving pydevd_reload.
authored
309 if isinstance(newobj, classmethod):
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
310 self._update_classmethod(oldobj, newobj)
311 return
312
4e1679f Fabio Zadrozny Improving pydevd_reload.
authored
313 if isinstance(newobj, staticmethod):
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
314 self._update_staticmethod(oldobj, newobj)
315 return
316
4e1679f Fabio Zadrozny Improving pydevd_reload.
authored
317 if hasattr(types, 'ClassType'):
318 classtype = (types.ClassType, type) #object is not instance of types.ClassType.
319 else:
320 classtype = type
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
321
4e1679f Fabio Zadrozny Improving pydevd_reload.
authored
322 if isinstance(newobj, classtype):
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
323 self._update_class(oldobj, newobj)
324 return
325
4e1679f Fabio Zadrozny Improving pydevd_reload.
authored
326 # New: dealing with metaclasses.
327 if hasattr(newobj, '__metaclass__') and hasattr(newobj, '__class__') and newobj.__metaclass__ == newobj.__class__:
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
328 self._update_class(oldobj, newobj)
329 return
330
331 if namespace is not None:
332
333 if oldobj != newobj and str(oldobj) != str(newobj) and repr(oldobj) != repr(newobj):
334 xreload_old_new = None
335 if is_class_namespace:
336 xreload_old_new = getattr(namespace, '__xreload_old_new__', None)
337 if xreload_old_new is not None:
338 xreload_old_new(name, oldobj, newobj)
339
340 elif '__xreload_old_new__' in namespace:
341 xreload_old_new = namespace['__xreload_old_new__']
342 xreload_old_new(namespace, name, oldobj, newobj)
343
344 else:
345 notify_info0('%s NOT updated. Create __xreload_old_new__(name, old, new) for custom reload' % (name,))
346
4e1679f Fabio Zadrozny Improving pydevd_reload.
authored
347 except:
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
348 notify_error('Exception found when updating %s. Proceeding for other items.' % (name,))
4e1679f Fabio Zadrozny Improving pydevd_reload.
authored
349 traceback.print_exc()
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
350
351
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
352 # All of the following functions have the same signature as _update()
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
353
354
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
355 def _update_function(self, oldfunc, newfunc):
356 """Update a function object."""
357 oldfunc.__doc__ = newfunc.__doc__
358 oldfunc.__dict__.update(newfunc.__dict__)
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
359
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
360 try:
361 newfunc.__code__
362 attr_name = '__code__'
363 except AttributeError:
364 newfunc.func_code
365 attr_name = 'func_code'
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
366
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
367 old_code = getattr(oldfunc, attr_name)
368 new_code = getattr(newfunc, attr_name)
369 if not code_objects_equal(old_code, new_code):
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
370 notify_info0('Updated function code:', oldfunc)
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
371 setattr(oldfunc, attr_name, new_code)
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
372
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
373 try:
374 oldfunc.__defaults__ = newfunc.__defaults__
375 except AttributeError:
376 oldfunc.func_defaults = newfunc.func_defaults
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
377
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
378 return oldfunc
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
379
380
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
381 def _update_method(self, oldmeth, newmeth):
382 """Update a method object."""
383 # XXX What if im_func is not a function?
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
384 if hasattr(oldmeth, 'im_func') and hasattr(newmeth, 'im_func'):
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
385 self._update(None, None, oldmeth.im_func, newmeth.im_func)
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
386 elif hasattr(oldmeth, '__func__') and hasattr(newmeth, '__func__'):
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
387 self._update(None, None, oldmeth.__func__, newmeth.__func__)
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
388 return oldmeth
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
389
390
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
391 def _update_class(self, oldclass, newclass):
392 """Update a class object."""
393 olddict = oldclass.__dict__
394 newdict = newclass.__dict__
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
395
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
396 oldnames = set(olddict)
397 newnames = set(newdict)
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
398
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
399 for name in newnames - oldnames:
400 setattr(oldclass, name, newdict[name])
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
401 notify_info0('Added:', name, 'to', oldclass)
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
402
403 # Note: not removing old things...
404 # for name in oldnames - newnames:
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
405 # notify_info('Removed:', name, 'from', oldclass)
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
406 # delattr(oldclass, name)
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
407
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
408 for name in (oldnames & newnames) - set(['__dict__', '__doc__']):
409 self._update(oldclass, name, olddict[name], newdict[name], is_class_namespace=True)
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
410
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
411 old_bases = getattr(oldclass, '__bases__', None)
412 new_bases = getattr(newclass, '__bases__', None)
413 if str(old_bases) != str(new_bases):
414 notify_error('Changing the hierarchy of a class is not supported. %s may be inconsistent.' % (oldclass,))
415
416 self._handle_namespace(oldclass, is_class_namespace=True)
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
417
418
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
419 def _update_classmethod(self, oldcm, newcm):
420 """Update a classmethod update."""
421 # While we can't modify the classmethod object itself (it has no
422 # mutable attributes), we *can* extract the underlying function
423 # (by calling __get__(), which returns a method object) and update
424 # it in-place. We don't have the class available to pass to
425 # __get__() but any object except None will do.
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
426 self._update(None, None, oldcm.__get__(0), newcm.__get__(0))
c03e6ac Fabio Zadrozny Fixed reload code to be Python 3 compatible.
authored
427
428
7b2801b Fabio Zadrozny Making the reload handle less to be more stable (i.e.: only update what ...
authored
429 def _update_staticmethod(self, oldsm, newsm):
430 """Update a staticmethod update."""
431 # While we can't modify the staticmethod object itself (it has no
432 # mutable attributes), we *can* extract the underlying function
433 # (by calling __get__(), which returns it) and update it in-place.
434 # We don't have the class available to pass to __get__() but any
435 # object except None will do.
39fde65 Fabio Zadrozny Improving pydevd_reload: more test-cases, hooks for clients, notifies wh...
authored
436 self._update(None, None, oldsm.__get__(0), newsm.__get__(0))
Something went wrong with that request. Please try again.