Currently, when you replace a class definition with an updated version, it's really difficult to change existing class instances; you'd have to essentially sweep every Python object and check if it's an instance, starting at roots such as __main__ and sys.modules. This makes developing code in a long-running process difficult, Zope being the best example of this. When you modify a class definition used by Zope code, you can't update existing instances floating around in memory. Over dinner, a friend and I were discussing this, and we thought it probably isn't difficult to add an extra level of indirection to allow fixing this. The only other option we could think of is either the complete scan of all objects, or inserting a forwarding pointer into PyClassObjects that points to the replacing class if !NULL, and then chase pointers when accessing PyInstanceObject->in_class. A quick hack to implement the extra indirection took about half an hour. It does these things: * Defines a PyClassHandle type: struct _PyClassHandle { PyClassHandle *next; /* ptr to next PyClassHandle in linked list */ PyClassObject *klass; /* The class object */ } ; * The in_class attribute of PyInstanceObject becomes a PyClassHandle* instead of a PyClassObject*, and all code such as inst->in_class becomes inst->in_class->klass. * As a quick hack to allow changing the class object referenced by a handle, I added a .forward( <newclassobject> ) method to class objects. This basically does self.handle->klass = <newclassobject>. The end result is that obj.__class__.forward(newclass) changes obj to be an instance of newclass, and all other instances of obj.__class__ also mutate to become newclass instances. Making this purely automatic seems hard; you'd have to catch things like 'import ftplib; ftplib.FTP = myclass', which would require automatically calling ftplib.FTP.forward( myclass ) to make all existing FTP instances mutate. Would it be worthwhile to export some hook for doing this in 1.6? The cost is adding an extra pointer deref to all access to PyInstanceObject->in_class. (This could probably also be added to ExtensionClass, and probably doesn't need to be added to core Python to help out Zope. Just a thought...) -- A.M. Kuchling http://starship.python.net/crew/amk/ Here the skull of a consumptive child becomes part of a great machine for calculating the motions of the stars. Here, a yellow bird frets within the ribcage of an unjust man. -- Welcome to Orqwith, in DOOM PATROL #22
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4