[Python-3000] My poor-man's non-oo implementation of my proposed interface and implements/implement syntax

Dave Anderson python3000 at davious.org
Fri Nov 24 22:15:24 CET 2006


class Interface(object):
	""" A hashable, type-identifiable 'list'
	
	The list should contain only other Interface objects
	, Classes/Types, or Class Methods/Attributes, and strings

	Interface objects can be used in specifying dispatch rules
	and function parameter "types"
	"""
	def __init__(self, *args):
		self.interfacelist = list(args)
	
class Implementation(dict):
	"""This is used just to indicate that implementation sets are
	dicts

	Reasoning is to allow for adaptation on the class or method 	
	level by a class reference pointing to a transform method
	or a class method reference pointing to a method definition
	(this is not implemented, though, and would be dependent on
	smart dispatching)
	"""
	pass

def implements(class_, *interface_objects):
	"""Declares that a class implements one or more interface
	objects
	
	See Interface class's description for allowed items
	"""
	for interface in interface_objects:
	
		# the implementation slot in a real implementation
		# would allows be an object attribute
		if not class_.__dict__.has_key('implementation'):
			class_.implementation = Implementation()
			
		# the class vouches to implement an Interface list			
		if isinstance(interface, Interface):
			class_.implementation[interface] = class_			
			
		# the class vouches to implement a class/type			
		if isinstance(interface, type):
			class_.implementation[interface] = class_
			
		# the class vouchers to implement a
		# non-class-specific method/attribute 			
		elif isinstance(interface, str):
			class_.implementation[interface] = interface
			
		# the class vouchers to implement a
		# class-specific method/attribute
		elif "__name__" in dir(interface):
			# this is a class-specific method:
			class_.implementation[interface] = \
			interface.__name__
			
		else:
			raise TypeError, interface, \
			 "must be an Interface, Class/Type, Class Method/Attribute, or string"

		
def implement(class_, obj, adaptor_or_method):
	"""a special adaption case for declaring an implementation
	
	   upon dispatch the adaptor_or_method value
	   would be used depending on context
	   class context:
	    apply adaptor_or_method to class instance to adapt
	   method context: use adaptor_or_method in the call
	"""
	if not class_.__dict__.has_key('implementation'):
		class_.implementation = Implementation()
	class_.implementation[obj] = adaptor_or_method


def does_implement(class_or_instance, *interface_objects):
	"""returns True or False depending on whether the class
	   implements

	   the list of interface objects
	"""

	# interface_objects can be an Interface object, a class, or
	# a class method/attribute
	
	class_ = class_or_instance
	if not isinstance(class_, type) and \
            not isinstance(class_, Interface):
		class_ = class_.__class__
	
	for interface in interface_objects:
	# interface is either a class/type or class method/attribute
	# or a string representation some name of a method or attribute
		
		# self or inherited classes are implemented
		if isinstance(interface, type) and \
                    isinstance(class_, interface):
			continue

		# interface is declared to be implemented
		# (interface is either a class or class
		# method/attribute)
		elif class_.__dict__.has_key('implementation') \
		 and interface in class_.implementation:
			continue

		# if this is a real interface
		# check each of the interfaces specified in it		
		elif isinstance(interface, Interface):
			# check the items within the interface
			if does_implement(class_,
                                           *interface.interfacelist):
				continue				

		# check non-class-specific method/attribute interfaces
		elif isinstance(interface, str) and \
                      interface in dir(class_):
			continue
				
		# check to see if the class is implemented
		# if a class specific the methods has not been declared
		elif 'im_class' in dir(interface) \
		 and does_implement(class_, interface.im_class):
			continue
			
		# recursive base implementations check
		elif class_.__dict__.has_key('implementation'):
			base_implementation = True
			for implementation in class_.implementation:
				if does_implement(implementation,
							interface):
					break
			else:	
				base_implementation = False
			
			if base_implementation:
				continue			

		return False

	return True


def test_prototype():
	"""Tests implementation of Guido's desired goals per bottom of
	http://mail.python.org/pipermail/python-3000/2006-November/004774.html
	"""
	class StandardMapping(object):
		def __getitem__(self):
			pass
		def __contains__(self):
			pass
		def keys(self):
			pass

	class Foo(object):
		pass
		
	implements(Foo, StandardMapping)
	
	print "does_implement(Foo, StandardMapping):",
	print does_implement(Foo, StandardMapping)
	print
	
	class StandardMutableMapping(object):
		pass
		
	implements(StandardMutableMapping, StandardMapping)	

	class dict_(dict):
		pass
	
	implements(dict_, StandardMutableMapping)
		
	print "does_implement(dict_, StandardMapping):",
	print does_implement(dict_, StandardMapping)
	print
	
	MinimalMapping = Interface(StandardMapping.__getitem__,
StandardMapping.__contains__, StandardMapping.keys)

	print "does_implement(dict_, MinimalMapping):",
	print does_implement(dict_, MinimalMapping)
	print
	
	ExtendedMapping = Interface(StandardMapping, "copy", "__eq__")	
	
	print "does_implement(dict_, ExtendedMapping):",
	print does_implement(dict_, ExtendedMapping)
	print
	
	implements(dict_, ExtendedMapping)	

	print "does_implement(dict_, ExtendedMapping):",
	print does_implement(dict_, ExtendedMapping)	
	print
	


More information about the Python-3000 mailing list