Hi, everybody. I wish someone could advise me. I'm running in circles, trying to find an elegant way to devise run-time pluggable classes. It all goes around method resolution order, I guess. (We already use various solutions, but the maintenance burden is high.)
We have a common module containing many basic classes, but for the sake of simplicity here, I'll use only Element and Connection. Next to this common module, we have many "plugin" modules importing it, and each plugin also defines an Element class having common.Element among its bases, and a Connection class having common.Connection among its bases. Or nearly, as some plugins just do not override common classes that just "fit" like they are. Plugins are really meant to enrich common classes. The common module and all plugins are part of a single package, but there are many other packages meant to provide work schemas, installed separately and maintained by different programmers. Each work schema package contains a core schema module which, after having imported the already installed common module above, defines tons of classes having either common.Element or common.Connection in their bases, relating them, and a schema class reaching everything, for applications to use. And finally, we have a flurry of applications. These applications import at least one and typically a few work schemas, and for each, specify _at run time_ which plugin to use (we use an URL-like syntax for specifying plugins, work schemas, and other various parameters, these URLs being read from configuration files while applications progress). So, while all work schemas are programmed to use classes from the common module, I would need at run time that all base classes be automatically "promoted" into plugin classes, depending on plugin as selected at run time, for being able to benefit from enriched methods. More or less, it might mean something like the virtual substitution of common classes by corresponding plugin classes whenever they appear in the class bases of work schemas, and consequently virtually altering the MRO of such classes so plugin methods override common methods, yet common methods staying available for fall back, that is, if not overridden by plugins. I feel ready to allow some complexity to the common module, but would like the overall approach to be as clean and unobtrusive as possible everywhere else, (that is, for plugins, work schemas, and applications). It ought to be overall simple. So, zealots: no Zope nor Twisted! :-). Another constraint is that the same work schema may be used at run-time with two different plugins, and this means that ideally, a work schema may not be altered (in a non-reentrant way) for a particular plugin. This is a lesser constraint, because it occurs only occasionally, and I presume that we could afford unusual stunts whenever necessary. -- François Pinard http://pinard.progiciels-bpi.ca -- http://mail.python.org/mailman/listinfo/python-list