[Zope-Checkins] CVS: Zope3/lib/python/Interface - Attribute.py:1.1.2.1 Document.py:1.1.2.1 IAttribute.py:1.1.2.1 IElement.py:1.1.2.1 IInterface.py:1.1.2.1 IMethod.py:1.1.2.1 Implements.py:1.1.2.1 Verify.py:1.1.2.1 _Element.py:1.1.2.1 _Interface.py:1.1.2.1 _InterfaceClass.py:1.1.2.1 Method.py:1.7.120.2 __init__.py:1.5.134.5 Attr.py:NONE Basic.py:NONE CHANGES.txt:NONE InterfaceBase.py:NONE Mapping.py:NONE Number.py:NONE README:NONE README.txt:NONE Standard.py:NONE Util.py:NONE iclass.py:NONE pprint.py:NONE pyfiles:NONE release.sh:NONE verify.py:NONE

Jim Fulton jim@zope.com
Tue, 5 Mar 2002 16:43:18 -0500


Update of /cvs-repository/Zope3/lib/python/Interface
In directory cvs.zope.org:/tmp/cvs-serv2132/Interface

Modified Files:
      Tag: Zope-3x-branch
	Method.py __init__.py 
Added Files:
      Tag: Zope-3x-branch
	Attribute.py Document.py IAttribute.py IElement.py 
	IInterface.py IMethod.py Implements.py Verify.py _Element.py 
	_Interface.py _InterfaceClass.py 
Removed Files:
      Tag: Zope-3x-branch
	Attr.py Basic.py CHANGES.txt InterfaceBase.py Mapping.py 
	Number.py README README.txt Standard.py Util.py iclass.py 
	pprint.py pyfiles release.sh verify.py 
Log Message:
Hold on to your butts!

Major refactoring of Interface package to clean up the interfaces and
module structure.

Note especially, to verify interface implementstions,
use verifyObject or verifyClass from the Interface.Verify module:

from Interface.Verify import verifyClass

verifyClass(ISomeInterface, SomeClass)



=== Added File Zope3/lib/python/Interface/Attribute.py ===
##############################################################################
#
# Copyright (c) 2001, 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
# 
##############################################################################
"""

Revision information:
$Id: Attribute.py,v 1.1.2.1 2002/03/05 21:42:46 jim Exp $
"""

from _Element import Element

class Attribute(Element):
    """Attribute descriptions
    """

    # We can't say this yet because we don't have enough
    # infrastructure in place.
    #
    #__implements__ = IAttribute




=== Added File Zope3/lib/python/Interface/Document.py ===
import string

""" Pretty-Print an Interface object as structured text (Yum) """


def trim_doc_string(text):
    """
    Trims a doc string to make it format
    correctly with structured text.
    """
    text=string.strip(text)
    text=string.replace(text, '\r\n', '\n')
    lines=string.split(text, '\n')
    nlines=[lines[0]]
    if len(lines) > 1:
        min_indent=None
        for line in lines[1:]:
            indent=len(line) - len(string.lstrip(line))
            if indent < min_indent or min_indent is None:
                min_indent=indent   
        for line in lines[1:]:
            nlines.append(line[min_indent:])
    return string.join(nlines, '\n')
    
    
    
def justify_and_indent(text, level, munge=0, width=72):
    """ indent and justify text, rejustify (munge) if specified """

    lines = []

    if munge:
        line = " " * level
        text = string.split(
                 string.strip(
                   string.translate(text, string.maketrans("\r\n", "  "))))

        for word in text:
            line = string.join([line, word])
            if len(line) > width:
                lines.append(line)
                line = " " * level
        else:
            lines.append(line)

        return string.join(lines, "\n")

    else:
        text = string.split(string.replace(text,"\r\n", "\n"), "\n")

        for line in text:
            lines.append( (" " * level) + line)

        return string.join(lines, "\n")
            

def interface_as_stx(I, munge=0):
    """ Output structured text format.  Note, this will wack any existing
    'structured' format of the text.  """

    outp = "%s\n\n" % I.getName()
    level = 1

    if I.getDoc():
        outp = ( outp
               + justify_and_indent(trim_doc_string(I.getDoc()), level)
               + "\n\n"
               )

    if I.getBases():
        outp = outp + (" " * level) + "This interface extends:\n\n"
        level = level + 1
        for b in I.getBases():
            item = "o %s" % b.getName()
            outp = ( outp
                   + justify_and_indent(trim_doc_string(item), level, munge)
                   + "\n\n"
                   )

        level = level - 1

    level = level + 1
    for name, desc in I.namesAndDescriptions():
        if hasattr(desc, 'getSignatureRepr'):   # ugh...
            item = "%s%s -- %s" % (desc.getName(),
                                   desc.getSignatureRepr(),
                                   desc.getDoc())
        else:
            item = "%s -- %s" % (desc.getName(), desc.getDoc())
            
        outp = ( outp
               + justify_and_indent(trim_doc_string(item), level, munge)
               + "\n\n"
               )

    return outp



    





=== Added File Zope3/lib/python/Interface/IAttribute.py ===
##############################################################################
#
# Copyright (c) 2001, 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
# 
##############################################################################
"""

Revision information:
$Id: IAttribute.py,v 1.1.2.1 2002/03/05 21:42:46 jim Exp $
"""

from IElement import IElement

class IAttribute(IElement):
    """Attribute descriptors"""
    


=== Added File Zope3/lib/python/Interface/IElement.py ===
##############################################################################
#
# Copyright (c) 2001, 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
# 
##############################################################################
"""

Revision information:
$Id: IElement.py,v 1.1.2.1 2002/03/05 21:42:46 jim Exp $
"""

from _Interface import Interface
from Attribute import Attribute

class IElement(Interface):
    """Objects that have basic documentation and tagged values.
    """

    __name__ = Attribute('__name__', 'The object name')
    __doc__  = Attribute('__doc__', 'The object doc string')

    def getName():
        """Returns the name of the object."""

    def getDoc():
        """Returns the documentation for the object."""
        
    def getTaggedValue(tag):
        """Returns the value associated with 'tag'."""

    def getTaggedValueTags():
        """Returns a list of all tags."""

    def setTaggedValue(tag, value):
        """Associates 'value' with 'key'."""


=== Added File Zope3/lib/python/Interface/IInterface.py ===
##############################################################################
#
# Copyright (c) 2001, 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
# 
##############################################################################
"""

Revision information:
$Id: IInterface.py,v 1.1.2.1 2002/03/05 21:42:46 jim Exp $
"""

from IElement import IElement

class IInterface(IElement):
    """Interface objects

    Interface objects describe the behavior of an object by containing
    useful information about the object.  This information includes:

      o Prose documentation about the object.  In Python terms, this
        is called the "doc string" of the interface.  In this element,
        you describe how the object works in prose language and any
        other useful information about the object.

      o Descriptions of attributes.  Attribute descriptions include
        the name of the attribute and prose documentation describing
        the attributes usage.

      o Descriptions of methods.  Method descriptions can include:

        o Prose "doc string" documentation about the method and its
          usage.

        o A description of the methods arguments; how many arguments
          are expected, optional arguments and their default values,
          the position or arguments in the signature, whether the
          method accepts arbitrary arguments and whether the method
          accepts arbitrary keyword arguments. 

      o Optional tagged data.  Interface objects (and their attributes and
        methods) can have optional, application specific tagged data
        associated with them.  Examples uses for this are examples,
        security assertions, pre/post conditions, and other possible
        information you may want to associate with an Interface or its
        attributes.

    Not all of this information is mandatory.  For example, you may
    only want the methods of your interface to have prose
    documentation and not describe the arguments of the method in
    exact detail.  Interface objects are flexible and let you give or
    take any of these components.

    Interfaces are created with the Python class statement using
    either Interface.Interface or another interface, as in::

      from Interface import Interface

      class IMyInterface(Interface):
        '''Interface documentation
        '''

        def meth(arg1, arg2):
            '''Documentation for meth
            '''

        # Note that there is no self argument

     class IMySubInterface(IMyInterface):
        '''Interface documentation
        '''

        def meth2():
            '''Documentation for meth2
            '''

    You use interfaces in two ways:

    o You assert that your object implement the interfaces.

      There are several ways that you can assert that an object
      implements an interface::

      1. Include an '__implements__' attribute in the object's class
         definition. The value of the '__implements__' attribute must
         be an implementation specification. An implementation
         specification is either an interface or a tuple of
         implementation specifications.

      2. Incluse an '__implements__' attribute in the object.
         Because Python classes don't have their own attributes, to
         assert that a class implements interfaces, you must provide a
         '__class_implements__' attribute in the class definition.

         **Important**: A class usually doesn't implement the
           interfaces that it's instances implement. The class and
           it's instances are separate objects with their own
           interfaces.

      3. Call 'Interface.Implements.implements' to assert that instances
         of a class implement an interface.

         For example::

           from Interface.Implements import implements

           implements(some_class, some_interface)

         This is approach is useful when it is not an option to modify
         the class source.  Note that this doesn't affect what the
         class itself implements, but only what it's instances
         implement.

      4. For types that can't be modified, you can assert that
         instances of the type implement an interface using
         'Interface.Implements.assertTypeImplements'.

         For example::

           from Interface.Implements import assertTypeImplements

           assertTypeImplements(some_type, some_interface)

    o You query interface meta-data. See the IInterface methods and
      attributes for details.

    """

    def getBases():
        """Return a sequence of the base interfaces
        """

    def extends(other, strict=1):
        """Test whether the interface extends another interface

        A true value is returned in the interface extends the other
        interface, and false otherwise.
        
        Normally, an interface doesn't extend itself. If a false value
        is passed as the second argument, or via the 'strict' keyword
        argument, then a true value will be returned if the interface
        and the other interface are the same.
        """

    def isImplementedBy(object):
        """Test whether the interface is implemented by the object.

        Return true of the object asserts that it implements the
        interface, including asseting that it implements an extended
        interface.
        """

    def isImplementedByInstancesOf(class_):
        """Test whether the interface is implemented by instances of the class

        Return true of the class asserts that it's instances implement the
        interface, including asseting that they implement an extended
        interface.
        """
    def names(all=0):
        """Get the interface attribute names.

        Return a sequence of the names of the attributes, including
        methods, included in the interface definition.

        Normally, only directly defined attributes are included. If
        a true positional or keyword argument is given, then
        attributes defined by nase classes will be included.
        """

    def namesAndDescriptions(all=0):
        """Get the interface attribute names and descriptions.

        Return a sequence of the names and descriptions of the
        attributes, including methods, as name-value pairs, included
        in the interface definition.

        Normally, only directly defined attributes are included. If
        a true positional or keyword argument is given, then
        attributes defined by nase classes will be included.
        """

    def getDescriptionFor(name, default=None):
        """Get the description for a name

        If no default is sepecified and the named attribute does not
        exist, a KeyError is raised.
        """


=== Added File Zope3/lib/python/Interface/IMethod.py ===
##############################################################################
#
# Copyright (c) 2001, 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
# 
##############################################################################
"""

Revision information:
$Id: IMethod.py,v 1.1.2.1 2002/03/05 21:42:46 jim Exp $
"""

from IAttribute import IAttribute

class IMethod(IAttribute):
    """Method attributes
    """
    # XXX What the heck should methods provide? Grrrr

    def getSignatureString():
        """Return a signature string suitable for inclusion in documentation.
        """


=== Added File Zope3/lib/python/Interface/Implements.py ===
##############################################################################
#
# Copyright (c) 2001, 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
# 
##############################################################################
"""Implemantation assertion facilities.

Revision information:
$Id: Implements.py,v 1.1.2.1 2002/03/05 21:42:46 jim Exp $
"""

import Exceptions
from types import ClassType
from Verify import verifyClass
from _InterfaceClass import Interface as InterfaceClass
from types import TupleType, ClassType, StringType

# Special value indicating the object supports
# what its class supports.
CLASS_INTERFACES = 1

try:
    import ExtensionClass
except ImportError:
    ClassTypes = (ClassType, type(object))
else:
    class dummy (ExtensionClass.Base): pass
    ClassTypes = (type(dummy), ClassType, type(object))

_typeImplements={}

def getImplements(object):
    t = type(object)
    if t in ClassTypes:
        if hasattr(object, '__class_implements__'):
            return object.__class_implements__
    elif hasattr(object, '__implements__'):
        return object.__implements__

    return _typeImplements.get(t, None)


def getImplementsOfInstances(klass, tiget=_typeImplements.get):
    if type(klass) in ClassTypes:
        if hasattr(klass, '__implements__'):
            return klass.__implements__
        else:
            return None
    elif hasattr(klass, 'instancesImplements'):
        # Hook for ExtensionClass. :)
        # XXX Potential security problem since "instancesImplements"
        # is a valid Zope identifier.
        return klass.instancesImplements()
    else:
        return tiget(klass, None)


def visitImplements(implements, object, visitor, getInterface=None):
    """
    Visits the interfaces described by an __implements__ attribute,
    invoking the visitor for each interface object.
    If the visitor returns anything true, the loop stops.
    This does not, and should not, visit superinterfaces.
    """
    if isinstance(implements, InterfaceClass):
        return visitor(implements)
    elif implements == CLASS_INTERFACES:
        klass = getattr(object, '__class__', None)
        if klass is not None:
            i = getImplementsOfInstances(klass)
            if i:
                return visitImplements(i, object, visitor, getInterface)
    elif type(implements) is StringType:
        if getInterface is not None:
            # Look up a named interface.
            i = getInterface(object, implements)
            if i is not None:
                return visitImplements(i, object, visitor, getInterface)
    elif type(implements) is TupleType:
        for i in implements:
            r = visitImplements(i, object, visitor, getInterface)
            if r:
                # If the visitor returns anything true, stop.
                return r
    else:
        raise Exceptions.BadImplements(
            """__implements__ should be an interface or tuple,
            not a %s""" % implements.__class__.__name__)
    return None


def assertTypeImplements(type, interfaces):
    """Return the interfaces implemented by objects of the given type
    """
    _typeImplements[type]=interfaces

def objectImplements(object, getInterface=None):
    r = []
    implements = getImplements(object)
    if not implements:
        return r
    visitImplements(implements, object, r.append, getInterface)
    return r

def instancesOfObjectImplements(klass, getInterface=None):
    r = []
    implements = getImplementsOfInstances(klass)
    if not implements:
        return r
    visitImplements(implements, klass, r.append, getInterface)
    return r


def _flatten(i, append):
    append(i)
    bases = i.getBases()
    if bases:
        for b in bases:
            _flatten(b, append)


def flattenInterfaces(interfaces, remove_duplicates=1):
    res = []
    for i in interfaces:
        _flatten(i, res.append)
    if remove_duplicates:
        # Remove duplicates in reverse.
        # Similar to Python 2.2's method resolution order.
        seen = {}
        index = len(res) - 1
        while index >= 0:
            i = res[index]
            if seen.has_key(i):
                del res[index]
            else:
                seen[i] = 1
            index = index - 1
    return res

def implements(klass, interface, check=1):
    if check:
        verifyClass(interface, klass, tentative=1)

    old=getattr(klass, '__implements__', None)
    if old is None:
        klass.__implements__ = interface
    else:
        klass.__implements__ = old, interface



=== Added File Zope3/lib/python/Interface/Verify.py ===

from Exceptions import BrokenImplementation, DoesNotImplement
from Exceptions import BrokenMethodImplementation
from types import FunctionType, MethodType
from Method import fromMethod, fromFunction

def _verify(iface, candidate, tentative=0, vtype=None):
    """

    Verify that 'candidate' might correctly implements 'iface'.
    This involves:

      o Making sure the candidate defines all the necessary methods

      o Making sure the methods have the correct signature

      o Making sure the candidate asserts that it implements the interface

    Note that this isn't the same as verifying that the class does
    implement the interface.

    If optional tentative is true, suppress the "is implemented by" test.
    """

    if vtype is 'c':
        tester = iface.isImplementedByInstancesOf
    else:
        tester = iface.isImplementedBy

    if not tentative and not tester( candidate ):
        raise DoesNotImplement(iface)

    for n, d in iface.namesAndDescriptions():
        if not hasattr(candidate, n):
            raise BrokenImplementation(iface, n)

        attr = getattr(candidate, n)
        if type(attr) is FunctionType:
            # should never get here
            meth = fromFunction(attr, n)
        elif type(attr) is MethodType:
            meth = fromMethod(attr, n)
        else:
            break # must be an attribute...

        d=d.getSignatureInfo()
        meth = meth.getSignatureInfo()

        mess = _incompat(d, meth)
        if mess:
            raise BrokenMethodImplementation(n, mess)
            
    return 1

def verifyClass(iface, candidate, tentative=0):
    return _verify(iface, candidate, tentative, vtype='c')

def verifyObject(iface, candidate, tentative=0):
    return _verify(iface, candidate, tentative, vtype='o')

def _incompat(required, implemented):
    #if (required['positional'] !=
    #    implemented['positional'][:len(required['positional'])]
    #    and implemented['kwargs'] is None):
    #    return 'imlementation has different argument names'
    if len(implemented['required']) > len(required['required']):
        return 'implementation requires too many arguments'
    if required['kwargs'] and not implemented['kwargs']:
        return "implementation doesn't support keyword arguments"
    if required['varargs'] and not implemented['varargs']:
        return "implementation doesn't support variable arguments"


=== Added File Zope3/lib/python/Interface/_Element.py ===
##############################################################################
#
# Copyright (c) 2001, 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
# 
##############################################################################
"""

Revision information:
$Id: _Element.py,v 1.1.2.1 2002/03/05 21:42:46 jim Exp $
"""

class Element:

    # We can't say this yet because we don't have enough
    # infrastructure in place.
    #
    #__implements__ = IElement

    __tagged_values = {}
    
    def __init__(self, __name__, __doc__=''):
        """Create an 'attribute' description
        """
        self.__name__=__name__
        self.__doc__=__doc__

    def getName(self):
        """ Returns the name of the object. """
        return self.__name__

    def getDoc(self):
        """ Returns the documentation for the object. """
        return self.__doc__

    def getTaggedValue(self, tag):
        """ Returns the value associated with 'tag'. """
        return self.__tagged_values[tag]

    def getTaggedValueTags(self):
        """ Returns a list of all tags. """
        return self.__tagged_values.keys()

    def setTaggedValue(self, tag, value):
        """ Associates 'value' with 'key'. """
        self.__tagged_values[tag] = value



=== Added File Zope3/lib/python/Interface/_Interface.py ===
##############################################################################
#
# Copyright (c) 2001, 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
# 
##############################################################################
"""Interface object implementation

Revision information:
$Id: _Interface.py,v 1.1.2.1 2002/03/05 21:42:46 jim Exp $
"""

from _InterfaceClass import Interface as InterfaceClass

Interface = InterfaceClass("Interface")

# Now we can create the interesting interfaces and wire them up:
def wire():

    from Implements import implements

    from Attribute import Attribute
    from IAttribute import IAttribute
    implements(Attribute, IAttribute)

    from Method import Method
    from IMethod import IMethod
    implements(Method, IMethod)

    from IInterface import IInterface
    implements(InterfaceClass, IInterface)

wire()
del wire 
del InterfaceClass


=== Added File Zope3/lib/python/Interface/_InterfaceClass.py ===
##############################################################################
#
# Copyright (c) 2001, 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
# 
##############################################################################
"""Interface object implementation

Revision information:
$Id: _InterfaceClass.py,v 1.1.2.1 2002/03/05 21:42:46 jim Exp $
"""

from inspect import currentframe
import sys
from Method import Method, fromFunction
from Attribute import Attribute
from types import FunctionType
import Exceptions
from _Element import Element

class Interface(Element):
    """Prototype (scarecrow) Interfaces Implementation
    """

    # We can't say this yet because we don't have enough
    # infrastructure in place.
    #
    #__implements__ = IInterface

    def __init__(self, name, bases=(), attrs=None, __doc__=None,
                 __module__=None):
        
        if __module__ is None:
            if attrs is not None and attrs.has_key('__module__'):
                __module__ = attrs['__module__']
                del attrs['__module__']
            else:
                try:
                    # Figure out what module defined the interface.
                    # This is how cPython figures out the module of
                    # a class, but of course it does it in C. :-/
                    __module__ = currentframe().f_back.f_globals['__name__']
                except (AttributeError, KeyError):
                    pass
        self.__module__ = __module__

        for b in bases:
            if not isinstance(b, Interface):
                raise TypeError, 'Expected base interfaces'
        self.__bases__=bases

        if attrs is None: attrs={}
        if attrs.has_key('__doc__'):
            if __doc__ is None: __doc__=attrs['__doc__']
            del attrs['__doc__']

        if __doc__ is not None:
            self.__doc__=__doc__
        else:
            self.__doc__ = ""

        Element.__init__(self, name, __doc__)



        for k, v in attrs.items():
            if isinstance(v, Method):
                v.interface=name
                v.__name__=k
            elif isinstance(v, FunctionType):
                attrs[k]=fromFunction(v, name)
            elif not isinstance(v, Attribute):
                raise Exceptions.InvalidInterface(
                    "Concrete attribute, %s" % k)

        self.__attrs = attrs

    def getBases(self):
        return self.__bases__

    def extends(self, other):
        """Does an interface extend another?
        """
        for b in self.__bases__:
            if b == other: return 1
            if b.extends(other): return 1
        return 0

    def isEqualOrExtendedBy(self, other):
        """Same interface or extends?
        """
        if self == other:
            return 1
        return other.extends(self)

    def isImplementedBy(self, object):
        """Does the given object implement the interface?
        """
        i = getImplements(object)
        if i is not None:
            return visitImplements(
                i, object, self.isEqualOrExtendedBy, self._getInterface)
        return 0

    def isImplementedByInstancesOf(self, klass):
        """Do instances of the given class implement the interface?
        """
        i = getImplementsOfInstances(klass)
        if i is not None:
            return visitImplements(
                i, klass, self.isEqualOrExtendedBy, self._getInterface)
        return 0

    def names(self):
        """Return the attribute names defined by the interface
        """
        return self.__attrs.keys()

    def namesAndDescriptions(self):
        """Return the attribute names and descriptions defined by the interface
        """
        return self.__attrs.items()

    def getDescriptionFor(self, name, default=None):
        """Return the attribute description for the given name
        """
        return self.__attrs.get(name, default)

    def deferred(self):
        """Return a defered class corresponding to the interface
        """
        if hasattr(self, "_deferred"): return self._deferred

        klass={}
        exec "class %s: pass" % self.__name__ in klass
        klass=klass[self.__name__]
        
        self.__d(klass.__dict__)

        self._deferred=klass

        return klass

    def _getInterface(self, ob, name):
        '''
        Retrieve a named interface.
        '''
        return None
            
    def __d(self, dict):

        for k, v in self.__attrs.items():
            if isinstance(v, Method) and not dict.has_key(k):
                dict[k]=v

        for b in self.__bases__: b.__d(dict)

    def __repr__(self):
        name = self.__name__
        m = self.__module__
        if m:
            name = '%s.%s' % (m, name)
        return "<%s %s at %x>" % (self.__class__.__name__, name, id(self))

    def __reduce__(self):
        return self.__name__

# We import this here to deal with module dependencies.
from Implements import getImplementsOfInstances, visitImplements, getImplements
from Implements import instancesOfObjectImplements


=== Zope3/lib/python/Interface/Method.py 1.7.120.1 => 1.7.120.2 ===
+#
+# Copyright (c) 2001, 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
+# 
+##############################################################################
 """Method interfaces
+
+Revision information:
+$Id$
 """
 import Exceptions
-from Attr import Attribute
+from Attribute import Attribute
 
 sig_traits = ['positional', 'required', 'optional', 'varargs', 'kwargs']
 
 CO_VARARGS = 4
 CO_VARKEYWORDS = 8
 
-class MethodClass:
-
-    def fromFunction(self, func, interface='', imlevel=0):
-        m=Method(func.__name__, func.__doc__)
-        defaults=func.func_defaults or ()
-        c=func.func_code
-        na=c.co_argcount-imlevel
-        names=c.co_varnames[imlevel:]
-        d={}
-        nr=na-len(defaults)
-        if nr < 0:
-            defaults=defaults[-nr:]
-            nr=0
-            
-        #if nr==0:
-        #    defaults=defaults[1:]
-        #    nr=1
-        
-        for i in range(len(defaults)):
-            d[names[i+nr]]=defaults[i]
-
-        m.positional=names[:na]
-        m.required=names[:nr]
-        m.optional=d
-
-        argno = na
-        if c.co_flags & CO_VARARGS:
-            m.varargs = names[argno]
-            argno = argno + 1
-        else:
-            m.varargs = None
-        if c.co_flags & CO_VARKEYWORDS:
-            m.kwargs = names[argno]
-        else:
-            m.kwargs = None
-
-        m.interface=interface
-        return m
-
-    def fromMethod(self, meth, interface=''):
-        func = meth.im_func
-        return self.fromFunction(func, interface, imlevel=1)
-
 class Method(Attribute):
     """Method interfaces
 
@@ -58,15 +31,12 @@
     This provides an opportunity for rich meta-data.
     """
 
-    fromFunction=MethodClass().fromFunction
-    fromMethod=MethodClass().fromMethod
-    interface=''
+    # We can't say this yet because we don't have enough
+    # infrastructure in place.
+    #
+    #__implements__ = IMethod
 
-    def __init__(self, __name__=None, __doc__=None):
-        """Create a 'method' description
-        """
-        self.__name__=__name__
-        self.__doc__=__doc__ or __name__
+    interface=''
 
     def __call__(self, *args, **kw):
         raise Exceptions.BrokenImplementation(self.interface, self.__name__)
@@ -97,6 +67,43 @@
         sig = sig + ")"
         return sig
 
+
+def fromFunction(func, interface='', imlevel=0):
+    m=Method(func.__name__, func.__doc__)
+    defaults=func.func_defaults or ()
+    c=func.func_code
+    na=c.co_argcount-imlevel
+    names=c.co_varnames[imlevel:]
+    d={}
+    nr=na-len(defaults)
+    if nr < 0:
+        defaults=defaults[-nr:]
+        nr=0
+
+    for i in range(len(defaults)):
+        d[names[i+nr]]=defaults[i]
+
+    m.positional=names[:na]
+    m.required=names[:nr]
+    m.optional=d
+
+    argno = na
+    if c.co_flags & CO_VARARGS:
+        m.varargs = names[argno]
+        argno = argno + 1
+    else:
+        m.varargs = None
+    if c.co_flags & CO_VARKEYWORDS:
+        m.kwargs = names[argno]
+    else:
+        m.kwargs = None
+
+    m.interface=interface
+    return m
+
+def fromMethod(meth, interface=''):
+    func = meth.im_func
+    return fromFunction(func, interface, imlevel=1)
 
 
 


=== Zope3/lib/python/Interface/__init__.py 1.5.134.4 => 1.5.134.5 ===
+#
+# Copyright (c) 2001, 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
+# 
+##############################################################################
+"""Interfaces
+
+This package implements the Python "scarecrow" proposal.
+
+The package exports a single name, 'Interface' directly. Interface
+is used to create an interface with a class statement, as in:
+
+  from Interface import Interface
+
+  class IMyInterface(Interface):
+    '''Interface documentation
+    '''
+
+    def meth(arg1, arg2):
+        '''Documentation for meth
+        '''
 
-from Standard import Base, InterfaceInterface
-Interface = Base
+    # Note that there is no self argument
 
-import iclass
-new=iclass.Interface
-CLASS_INTERFACES = iclass.CLASS_INTERFACES
-# del iclass
+To find out what you can do with interfaces, see the interface
+interface, IInterface in the IInterface module.
 
-from Util import impliedInterface
-from Util import assertTypeImplements, objectImplements
-from Util import instancesOfObjectImplements
+The package has several public modules:
+    
+  o Attribute has the implementation for interface attributes
+    for people who want to build interfaces by hand.
+    (Maybe someone should cry YAGNI for this. ;)
 
-from Attr import Attribute
-from Method import Method
+  o Document has a utility for documenting an interface as structured text.
 
-from Exceptions import BrokenImplementation
+  o Exceptions has the interface-defined exceptions
 
-from pprint import interface_as_stx
-from verify import verify, verify_class_implementation
+  o IAttribute defines the attribute descriptor interface.
+
+  o IElement defined the base interface for IAttribute, IInterface,
+    and IMethod.
+
+  o IInterface defines the interface interface
+
+  o IMethod defined the method interface.
+
+  o Implements has various utilities for examining interface assertions.
+
+  o Method has the implementation for interface methods. See above.
+
+  o Verify has utilities for verifying (sort of) interfaces.
+
+See the module doc strings for more information.
+
+There is also a script, pyself.py in the package that can be used to
+create interface skeletins. Run it without arguments to get documentation.
+
+Revision information:
+$Id$
+"""
+
+from _Interface import Interface
+Base = Interface # XXX We need to stamp out Base usage
 
-from Util import implements
-    

=== Removed File Zope3/lib/python/Interface/Attr.py ===

=== Removed File Zope3/lib/python/Interface/Basic.py ===

=== Removed File Zope3/lib/python/Interface/CHANGES.txt ===

=== Removed File Zope3/lib/python/Interface/InterfaceBase.py ===

=== Removed File Zope3/lib/python/Interface/Mapping.py ===

=== Removed File Zope3/lib/python/Interface/Number.py ===

=== Removed File Zope3/lib/python/Interface/README ===

=== Removed File Zope3/lib/python/Interface/README.txt ===

=== Removed File Zope3/lib/python/Interface/Standard.py ===

=== Removed File Zope3/lib/python/Interface/Util.py ===

=== Removed File Zope3/lib/python/Interface/iclass.py ===

=== Removed File Zope3/lib/python/Interface/pprint.py ===

=== Removed File Zope3/lib/python/Interface/pyfiles ===

=== Removed File Zope3/lib/python/Interface/release.sh ===

=== Removed File Zope3/lib/python/Interface/verify.py ===