Commit b3b2584c authored by Chris McDonough's avatar Chris McDonough

For "old" Interface packages b/w compatibility:

  Because the "old" Interface package allowed the import of the Attribute
  class directly from the Interface package, and some packages
  (such as CMF) expect a class back from "from Interface import Attribute":

  - Renamed Attribute.py to _Attribute.py and did the necessary
    housekeeping to make sure all the other parts of the Interface
    package knows about the change.

  - Changed __init__.py to import Attribute from _Attribute

New features and changes:

  - Removed iclass.py  (it was no longer used).

  - Gave the base interface class (Interface._InterfaceClass) a __hash__
    method as ExtensionClass instances do not hash like normal
    instances, and we require that interfaces be hashable in order to
    store them as dictionary keys and whatnot in registries.
parent c127663e
......@@ -14,11 +14,11 @@
"""
Revision information:
$Id: IElement.py,v 1.2 2002/06/07 17:18:29 jim Exp $
$Id: IElement.py,v 1.3 2002/06/10 16:47:38 chrism Exp $
"""
from _Interface import Interface
from Attribute import Attribute
from _Attribute import Attribute
class IElement(Interface):
"""Objects that have basic documentation and tagged values.
......
......@@ -14,10 +14,10 @@
"""Method interfaces
Revision information:
$Id: Method.py,v 1.9 2002/06/07 17:18:29 jim Exp $
$Id: Method.py,v 1.10 2002/06/10 16:47:38 chrism Exp $
"""
import Exceptions
from Attribute import Attribute
from _Attribute import Attribute
sig_traits = ['positional', 'required', 'optional', 'varargs', 'kwargs']
......
......@@ -14,7 +14,7 @@
"""
Revision information:
$Id: Attribute.py,v 1.2 2002/06/07 17:18:29 jim Exp $
$Id: _Attribute.py,v 1.1 2002/06/10 16:47:38 chrism Exp $
"""
from _Element import Element
......
......@@ -14,7 +14,7 @@
"""Interface object implementation
Revision information:
$Id: _Interface.py,v 1.2 2002/06/07 17:18:29 jim Exp $
$Id: _Interface.py,v 1.3 2002/06/10 16:47:38 chrism Exp $
"""
from _InterfaceClass import Interface as InterfaceClass
......@@ -26,7 +26,7 @@ def wire():
from Implements import implements
from Attribute import Attribute
from _Attribute import Attribute
from IAttribute import IAttribute
implements(Attribute, IAttribute)
......
......@@ -14,13 +14,13 @@
"""Interface object implementation
Revision information:
$Id: _InterfaceClass.py,v 1.2 2002/06/07 17:18:29 jim Exp $
$Id: _InterfaceClass.py,v 1.3 2002/06/10 16:47:38 chrism Exp $
"""
from inspect import currentframe
import sys
from Method import Method, fromFunction
from Attribute import Attribute
from _Attribute import Attribute
from types import FunctionType
import Exceptions
from _Element import Element
......@@ -213,6 +213,12 @@ class Interface(Element):
def __reduce__(self):
return self.__name__
def __hash__(self):
""" interface instances need to be hashable, and inheriting
from extensionclass makes instances unhashable unless we declare
a __hash__ method here"""
return id(self)
# We import this here to deal with module dependencies.
from Implements import getImplementsOfInstances, visitImplements, getImplements
from Implements import instancesOfObjectImplements
......@@ -64,9 +64,10 @@ 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: __init__.py,v 1.6 2002/06/07 17:18:29 jim Exp $
$Id: __init__.py,v 1.7 2002/06/10 16:47:38 chrism Exp $
"""
from _Interface import Interface
from _Attribute import Attribute
Base = Interface # XXX We need to stamp out Base usage
"""Python Interfaces
Scarecrow version:
Classes or objects can implement an __implements__ attribute that
names an interface object or a collection of interface objects.
An interface is defined using the class statement and one or more base
interfaces.
"""
from Method import Method
from Attr import Attribute
from types import FunctionType, ClassType
import Exceptions
from InterfaceBase import InterfaceBase
from _object import ClassTypes, isInstance
_typeImplements={}
class Interface(InterfaceBase):
"""Prototype (scarecrow) Interfaces Implementation
"""
def __init__(self, name, bases=(), attrs=None, __doc__=None):
"""Create a new interface
"""
for b in bases:
if not isInstance(b, Interface):
raise TypeError, 'Expected base interfaces'
self.__bases__=bases
self.__name__=name
if attrs is None: attrs={}
if attrs.has_key('__doc__'):
if __doc__ is None: __doc__=attrs['__doc__']
del attrs['__doc__']
if attrs.has_key('__module__'):
self.__module__ = attrs['__module__']
del attrs['__module__']
if __doc__ is not None:
self.__doc__=__doc__
else:
self.__doc__ = ""
for k, v in attrs.items():
if isInstance(v, Method):
v.interface=name
v.__name__=k
elif isInstance(v, FunctionType):
attrs[k]=Method.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 is other: return 1
if b.extends(other): return 1
return 0
def isImplementedBy(self, object,
tiget=_typeImplements.get):
"""Does the given object implement the interface?
"""
t=type(object)
if t in ClassTypes:
if hasattr(object, '__class_implements__'):
implements=object.__class_implements__
else: implements=Class
elif hasattr(object, '__implements__'):
implements=object.__implements__
else:
implements=tiget(t, None)
if implements is None: return 0
if isInstance(implements,Interface):
return implements is self or implements.extends(self)
else:
return self.__any(implements)
def isImplementedByInstancesOf(self, klass,
tiget=_typeImplements.get):
"""Do instances of the given class implement the interface?
"""
if type(klass) in ClassTypes:
if hasattr(klass, '__implements__'):
implements=klass.__implements__
else: return 0
elif hasattr(klass, 'instancesImplement'):
# Hook for ExtensionClass. :)
implements=klass.instancesImplement()
else:
implements=tiget(klass,None)
if implements is None: return 0
if isInstance(implements,Interface):
return implements is self or implements.extends(self)
else:
return self.__any(implements)
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 defrered 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 __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 __any(self, interfaces):
for i in interfaces:
if isInstance(i,Interface):
if i is self or i.extends(self): return 1
else:
if self.__any(i): return 1
return 0
def __repr__(self):
return "<Interface %s at %x>" % (self.__name__, id(self))
Base=Interface("Interface")
class Named(Base):
"Objects that have a name."
__name__ = Attribute("The name of the object")
class Class(Named):
"""Implement shared instance behavior and create instances
Classes can be called to create an instance. This interface does
not specify what if any arguments are required.
"""
# Note that we don't use a function definition here, because
# we don't want to specify a signature!
__call__=Method("Instantiate instances of the class")
__bases__=Attribute("A sequence of base classes")
def assertTypeImplements(type, interfaces):
"""Return the interfaces implemented by objects of the given type
"""
_typeImplements[type]=interfaces
class InterfaceBaseInterface(Base):
"""
A base class that defines a common Interface inteface.
"""
def getName(self):
"""
Returns the name of the current interface object.
"""
def getDoc(self):
"""
Returns the documentation for the current interface object.
"""
class InterfaceInterface(InterfaceBaseInterface):
"""
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.
"""
def getBases(self):
"""
Returns a sequence of base interfaces this interface extends.
"""
def extends(self, other):
"""
"""
Interface.__implements__ = (InterfaceInterface,)
......@@ -25,7 +25,7 @@ Example:
The dotted name is the module name and interface object name connected
with a dot.
Revision information: $Id: pyskel.py,v 1.2 2002/06/07 17:18:29 jim Exp $
Revision information: $Id: pyskel.py,v 1.3 2002/06/10 16:47:38 chrism Exp $
"""
import sys, os, re
......@@ -36,7 +36,7 @@ from _object import isInstance
from types import ModuleType
from Interface.Method import Method
from Interface.Attribute import Attribute
from Interface._Attribute import Attribute
class_re = re.compile(r'\s*class\s+([a-zA-Z_][a-zA-Z0-9_]*)')
def_re = re.compile(r'\s*def\s+([a-zA-Z_][a-zA-Z0-9_]*)')
......
......@@ -14,12 +14,12 @@
"""
Revision information:
$Id: testDocument.py,v 1.2 2002/06/07 17:18:29 jim Exp $
$Id: testDocument.py,v 1.3 2002/06/10 16:47:38 chrism Exp $
"""
from unittest import TestCase, TestSuite, main, makeSuite
from Interface import Interface
from Interface.Attribute import Attribute
from Interface._Attribute import Attribute
class Test(TestCase):
......
......@@ -19,7 +19,7 @@ from Interface.Exceptions import BrokenImplementation
from Interface.Implements import instancesOfObjectImplements
from Interface.Implements import objectImplements
from Interface import Interface
from Interface.Attribute import Attribute
from Interface._Attribute import Attribute
class InterfaceTests(unittest.TestCase):
......
......@@ -12,7 +12,7 @@
#
##############################################################################
from Interface import Interface
from Interface.Attribute import Attribute
from Interface._Attribute import Attribute
class mytest(Interface):
pass
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment