[Zope3-checkins] CVS: Zope3/lib/python/Interface/Registry - AdapterRegistry.py:1.1 IAdapterRegistry.py:1.1 IImplementorRegistry.py:1.1 ITypeRegistry.py:1.1 ImplementorRegistry.py:1.1 TypeRegistry.py:1.1 __init__.py:1.1 _flatten.py:1.1
Jim Fulton
jim@zope.com
Thu, 1 Aug 2002 11:33:44 -0400
Update of /cvs-repository/Zope3/lib/python/Interface/Registry
In directory cvs.zope.org:/tmp/cvs-serv4877/lib/python/Interface/Registry
Added Files:
AdapterRegistry.py IAdapterRegistry.py IImplementorRegistry.py
ITypeRegistry.py ImplementorRegistry.py TypeRegistry.py
__init__.py _flatten.py
Log Message:
Refactored and moved Zope.ComponentArchitecture.IToIRegistry into
Interface.Registry. This is only the first step. The tests pass and
Zope 3 runs, but there are a bunch of wrong dependencies that still
need to get cleaned up, which is my next task.
=== Added File Zope3/lib/python/Interface/Registry/AdapterRegistry.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Adapter-style interface registry
See Adapter class.
$Id: AdapterRegistry.py,v 1.1 2002/08/01 15:33:43 jim Exp $
"""
__metaclass__ = type # All classes are new style when run with Python 2.2+
from Interface import Interface
from _flatten import _flatten
from IAdapterRegistry import IAdapterRegistry
class AdapterRegistry:
"""Adapter-style interface registry
"""
__implements__ = IAdapterRegistry
# The implementation uses a mapping:
#
# { (required_interface, provided_interface) ->
# (registered_provides, component) }
#
# Where the registered provides is what was registered and
# provided may be some base interface
def __init__(self):
self._reg = {}
def _registerAllProvided(self, require, primary_provide, object, provide):
# Registers a component using (require, provide) as a key.
# Also registers superinterfaces of the provided interface,
# stopping when the registry already has a component
# that provides a more general interface or when the Base is Interface.
reg = self._reg
reg[(require, provide)] = (primary_provide, object)
bases = getattr(provide, '__bases__', ())
for base in bases:
if base is Interface:
# Never register the say-nothing Interface.
continue
existing = reg.get((require, base), None)
if existing is not None:
existing_provide = existing[0]
if existing_provide is not primary_provide:
if not existing_provide.extends(primary_provide):
continue
# else we are registering a general component
# after a more specific component.
self._registerAllProvided(require, primary_provide, object, base)
def register(self, require, provide, object):
self._registerAllProvided(require, provide, object, provide)
def get(self, (ob_interface, provide), default=None):
"""
Finds a registered component that provides the given interface.
Returns None if not found.
"""
for interface in _flatten(ob_interface):
c = self._reg.get((interface, provide))
if c:
return c[1]
c = self._reg.get((None, provide), default)
if c:
return c[1]
return c
def getForObject(self, object, interface):
return self.get((getattr(object, '__implements__', None), interface))
=== Added File Zope3/lib/python/Interface/Registry/IAdapterRegistry.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
$Id: IAdapterRegistry.py,v 1.1 2002/08/01 15:33:43 jim Exp $
"""
from Interface import Interface
class IAdapterRegistry(Interface):
"""Adapter-style registry
This registry stores objects registered to convert (or participate
in the conversion from) one interface to another. The interface
converted is the "required" interface. We say that the interface
converted to is the "provided" interface.
The objects registered here don't need to be adapters. What's
important is that they are registered according to a required and
a provided interface.
The provided interface may not be None.
The required interface may be None. Adapters with a required
interface of None adapt non-components. An adapter that adapts all
components should specify a required interface of
Interface.Interface.
"""
def register(require, provide, object):
"""Register an object for a required and provided interface.
There are no restrictions on what the object might be.
Any restrictions (e.g. callability, or interface
implementation) must be enforced by higher-level code.
The require argument may be None.
"""
def get((implements, provides), default=None):
"""Return a registered object
The registered object is one that was registered to require an
interface that one of the interfaces in the 'implements'
specification argument extends or equals and that provides an
interface that extends or equals the 'provides' argument. An
attempt will be made to find the component that most closely
matches the input arguments.
The object returned could have been registred to require None.
Note that the implements may be None, it which case a
component will be returned only if it was registered with a
require of None.
"""
=== Added File Zope3/lib/python/Interface/Registry/IImplementorRegistry.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
$Id: IImplementorRegistry.py,v 1.1 2002/08/01 15:33:43 jim Exp $
"""
from Interface import Interface
class IImplementorRegistry(Interface):
"""Implementor registry
This registry stores objects registered to implement (or help
implement) an interface. For example, this registry could be used
to register utilities.
The objects registered here don't need to be implementors. (They
might just be useful to implementation.) What's important is that
they are registered according to a provided interface.
"""
def register(provide, object):
"""Register an object for a required and provided interface.
There are no restrictions on what the object might be.
Any restrictions (e.g. callability, or interface
implementation) must be enforced by higher-level code.
The require argument may be None.
"""
def get(provides, default=None):
"""Return a registered object
The registered object is one that was registered that provides an
interface that extends or equals the 'provides' argument.
"""
=== Added File Zope3/lib/python/Interface/Registry/ITypeRegistry.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
$Id: ITypeRegistry.py,v 1.1 2002/08/01 15:33:43 jim Exp $
"""
from Interface import Interface
class ITypeRegistry(Interface):
"""Type-specific registry
This registry stores objects registered for objects that implement
a required interface.
"""
def register(require, object):
"""Register an object for a required interface.
The require argument may be None. This effectively defines a
default object.
"""
def get(implements, default=None):
"""Return a registered object
The registered object is one that was registered to require an
interface that one of the interfaces in the 'implements'
specification argument extends or equals. An attempt will be
made to find the component that most closely matches the input
arguments.
The object returned could have been registred to require None.
Note that the implements may be None, it which case a
component will be returned only if it was registered with a
require of None.
"""
def getDefinitions(implements=None):
"""Get meta-data about registered objects
Return meta data for all objects registered with a require
interfaces such that if the 'implements' argumennt is not
None, it is an implementation specification such that some of
the interfaces in the specification extend or equal the
require interface (or the require interface was None).
The meta-data returned is a sequence of mapping objects with
the following keys:
require -- The required interface
object -- The registered object
"""
def getAll(implements=None):
"""Get registered objects
Return all objects registered with a require interfaces such
that if the 'implements' argumennt is not None, it is an
implementation specification such that some of the interfaces
in the specification extend or equal the require interface (or
the require interface was None).
"""
=== Added File Zope3/lib/python/Interface/Registry/ImplementorRegistry.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Adapter-style interface registry
See Adapter class.
$Id: ImplementorRegistry.py,v 1.1 2002/08/01 15:33:43 jim Exp $
"""
__metaclass__ = type # All classes are new style when run with Python 2.2+
from Interface import Interface
from IImplementorRegistry import IImplementorRegistry
class ImplementorRegistry:
"""Implementor-style interface registry
"""
__implements__ = IImplementorRegistry
# The implementation uses a mapping:
#
# { provided_interface -> (registered_provides, component) }
#
# Where the registered provides is what was registered and
# provided may be some base interface
def __init__(self):
self._reg = {}
def _registerAllProvided(self, primary_provide, object, provide):
# Registers a component using (require, provide) as a key.
# Also registers superinterfaces of the provided interface,
# stopping when the registry already has a component
# that provides a more general interface or when the Base is Interface.
reg = self._reg
reg[provide] = (primary_provide, object)
bases = getattr(provide, '__bases__', ())
for base in bases:
if base is Interface:
# Never register the say-nothing Interface.
continue
existing = reg.get(base, None)
if existing is not None:
existing_provide = existing[0]
if existing_provide is not primary_provide:
if not existing_provide.extends(primary_provide):
continue
# else we are registering a general component
# after a more specific component.
self._registerAllProvided(primary_provide, object, base)
def register(self, provide, object):
self._registerAllProvided(provide, object, provide)
def get(self, provide, default=None):
"""
Finds a registered component that provides the given interface.
Returns None if not found.
"""
c = self._reg.get(provide)
if c is not None:
return c[1]
return default
=== Added File Zope3/lib/python/Interface/Registry/TypeRegistry.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Adapter-style interface registry
See Adapter class.
$Id: TypeRegistry.py,v 1.1 2002/08/01 15:33:43 jim Exp $
"""
__metaclass__ = type # All classes are new style when run with Python 2.2+
from Interface import Interface
from _flatten import _flatten
from ITypeRegistry import ITypeRegistry
class TypeRegistry:
"""Type registry
"""
__implements__ = ITypeRegistry
# The implementation uses a mapping:
#
# { (required_interface, provided_interface) ->
# (registered_provides, component) }
#
# Where the registered provides is what was registered and
# provided may be some base interface
def __init__(self):
self._reg = {}
def register(self, interface, object):
self._reg[interface] = object
def get(self, interface, default=None):
"""
Finds a registered component that provides the given interface.
Returns None if not found.
"""
return self._reg.get(interface, default)
def getAll(self, interface_spec):
result = []
for interface in _flatten(interface_spec):
object = self._reg.get(interface)
if object is not None:
result.append(object)
if interface_spec is not None:
object = self._reg.get(None)
if object is not None:
result.append(object)
return result
def getAllForObject(self, object):
# XXX This isn't quite right, since it doesn't take into
# account implementation registries for objects that can't
# have '__implements__' attributes.
return self.getAll(getattr(object, '__implements__', None))
=== Added File Zope3/lib/python/Interface/Registry/__init__.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
=== Added File Zope3/lib/python/Interface/Registry/_flatten.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Adapter-style interface registry
See Adapter class.
$Id: _flatten.py,v 1.1 2002/08/01 15:33:43 jim Exp $
"""
__metaclass__ = type # All classes are new style when run with Python 2.2+
from Interface import Interface
def _flatten(implements):
"""Flatten an implements spec to a list of interfaces
The list includes all base interfaces of the interface(s) in
implements. Each interface is listed only once and more
specific interfaces are listed before less specific
interfaces. This is similar to Python 2.2's MRO.
"""
interfaces = []
_flatten_recurse(implements, interfaces)
interfaces.reverse()
seen = {}
flattened = []
for interface in interfaces:
if interface not in seen:
seen[interface] = 1
flattened.append(interface)
flattened.reverse()
return flattened
def _flatten_recurse(implements, list):
if implements.__class__ == tuple:
for i in implements:
_flatten_recurse(i, list)
else:
_flatten_recurse_interface(implements, list)
def _flatten_recurse_interface(interface, list):
list.append(interface)
if interface is None:
return
for i in interface.__bases__:
_flatten_recurse_interface(i, list)