[TransWarp] Configuration and Providers - final implementation plan (I hope!)

Phillip J. Eby pje at telecommunity.com
Fri Jul 12 16:46:15 EDT 2002

peak.binding.components additions:

Component.acquireProvider(iface, forObj=None, localLookup=True) -- check
the component's __instance_provides__, __class_provides__, and
getParentComponent().acquireProvider(), in that order.  Return None if not
found.  If localLookup is false, skip local lookups and proceed to parent
component or config.getLocal(self), as appropriate.  (Note: may need a
recursion check when looking up local attrs.)

Component.registerProvider(ifaces, provider) -- register provider in

Component.__instance_provides__ -- binding.bindToNew(EigenRegistry)

new API's: Provider(callable), CachingProvider(callable, weak=False)

peak.binding.components changes:

lookupComponent() - check if target is interface, and use acquireProvider()
instead; raise an error if acquireProvider() returns None.  This will make
it possible to use binding.bindTo(ISomeInterface) to define an attribute.

all binding functions: add support for specifying "provides=" keyword
parameter, to signify that the bound attribute can be used to provide that
interface to sub-components.  Needs to create a __class_provides__
attribute via conservative merge and register the attribute name under the
supplied interface(s).

peak.util.EigenData changes:

EigenRegistry._register() - needs to use Zope 3-compatible algorithm, but
check at interface as well as its bases!

EigenRegistry.update() - needs to do "conservative merge"

peak.running.config.api additions:

config.getGlobal() -- Return the global configuration component

config.setGlobal() -- Set the global configuration component; only works if
getGlobal() hasn't been called

config.getLocal(forRoot=None) -- Return the local configuration component
for 'forRoot'.

config.setLocal(component,forRoot=None) -- Set the configuration component
to be retrieved by config.getLocal(forRoot); only works if
getLocal(forRoot) hasn't been called yet.

config.registerLocalProvider(ifaces, provider, forRoot=None) -- a synonym
for config.getLocal(forRoot).registerProvider(ifaces, provider)

config.registerGlobalProvider(ifaces, provider) -- a synonym for
config.getGlobal().registerProvider(ifaces, provider)

Also...  need to define a root component class to be used for getGlobal(),
and a similar class for getLocal().  The latter will implement
acquireProvider() in such a way that providers are never instantiated
around the global config component, only around a local config component.
(This ensures that local configuration will always override global
configuration, even for providers registered with the global configuration.)

peak.naming changes:

Refactor contexts, interfaces, and API/SPI to get rid of "environment"
parameters, make contexts into binding.Components, use provider lookups to
find factories/etc., and move registry-style configuration (e.g. URL
scheme->parser and scheme->context registries) to be registries looked up
via acquireProvider() bindings.

More information about the PEAK mailing list