Support for interface checking. Experimental.

git-svn-id: svn://svn.code.sf.net/p/fonttools/code/trunk@68 4cde692c-a291-49d1-8350-778aa11640f8
This commit is contained in:
Just 2000-01-26 19:20:06 +00:00
parent 02a739a0d5
commit 56804d237a

89
Lib/interfaceChecker.py Normal file
View File

@ -0,0 +1,89 @@
import sys, types
try:
import describeFunction
except ImportError:
print "(Can't check interfaces, describeFunction could not be imported)"
describeFunction = None
def collectMethodNames(theClass, names=None):
if names is None:
names = {}
names.update(theClass.__dict__)
for baseClass in theClass.__bases__:
collectMethodNames(baseClass, names)
names = names.keys()
names.sort()
return names
def checkClass(moduleName, theClass):
className = theClass.__name__
if theClass.__module__ <> moduleName:
return
if not hasattr(theClass, "__implements__"):
print "Interfaceless class: %s (%s)" % (className, theClass.__module__)
return
interfaces = theClass.__implements__
if interfaces is None:
return
if isinstance(interfaces, types.ClassType):
interfaces = (interfaces,)
gotOne = 0
for interface in interfaces:
methodNames = collectMethodNames(interface)
methodNames.sort()
for methodName in methodNames:
method = getattr(interface, methodName)
if not isinstance(method, types.UnboundMethodType):
continue
method = method.im_func
if not hasattr(theClass, methodName):
if not gotOne:
print "\nWarnings for module %s\n" % moduleName
gotOne = 1
print "class %s misses required method:\n %s" % (className, describeFunction.describe(method))
continue
method2 = getattr(theClass, methodName).im_func
argList = describeFunction._describe(method)
argList2 = describeFunction._describe(method2)
if len(argList2) < len(argList):
if not gotOne:
print "\nWarnings for module %s\n" % moduleName
gotOne = 1
print "Method has not enough arguments:"
print " interface: %s.%s" % (className, describeFunction.describe(method))
print " implementation: %s.%s" % (className, describeFunction.describe(method2))
continue
for i in range(len(argList)):
if argList[i] <> argList2[i]:
if not gotOne:
print "\nWarnings for module %s\n" % moduleName
gotOne = 1
print "Method has different arguments:"
print " interface: %s.%s" % (className, describeFunction.describe(method))
print " implementation: %s.%s" % (className, describeFunction.describe(method2))
break
for arg in argList2[len(argList):]:
if type(arg) == types.StringType:
if not gotOne:
print "\nWarnings for module %s\n" % moduleName
gotOne = 1
print "Additional argument(s) should have default value(s):"
print " interface: %s.%s" % (className, describeFunction.describe(method))
print " implementation: %s.%s" % (className, describeFunction.describe(method2))
break
def checkInterface(moduleName):
if describeFunction is None:
return
items = sys.modules[moduleName].__dict__.items()
items.sort()
for name, value in items:
if not isinstance(value, types.ClassType):
continue
checkClass(moduleName, value)