RFC: reimplementing the Type type as an extension type.

Huaiyu Zhu hzhu at yahoo.com
Wed Oct 4 11:48:32 CEST 2000


On Tue, 03 Oct 2000 16:14:07 GMT, Tom <nospam at nospam.com> wrote:
>I'm thinking about reimplementing the type type as an extension type.  The
>purpose would be to make much additional information about a type available
>from the type object.  This info would include the following:

You might also want to consider ideas contained in the following example.
The rationale is explained in

http://www.geocities.com/huaiyu_zhu/python/Interface/README.txt

Huaiyu

===================================================================

#!/usr/bin/env python
# $Id: test.py,v 1.1.1.1 2000/08/29 00:38:54 hzhu Exp $
"""
A simulated type checking system
Types are inherited by abstraction

"""

class Type:
	def __init__(self, name):
		"Define a new abstract Type"
		self.name = name
		self.types = []
		self.classes = []
		self.subs = []
		self.attrs = []
		self.objs = []
		
	def include(self, obj):
		"Check to see if object is of my Type"
		
		# If it is explicitly included objects
		for o in self.objs:
			if obj == o: return 1

		# If it is of the right type or class
		if type(obj) is type(Type):
			for c in self.classes:
				if isinstance(obj, c): return 1
		else:
			for t in self.types:
				if type(obj) == t: return 1

		# If it is one of our sub-Type
		for s in self.subs:
			if s.include(obj): return 1
		else:
			return 0

	def satisfiedby(self, obj):
		"""Check to see if object has all the required attributes
		Is this necessary? """
		for a in self.attrs:
			if not hasattr(obj, a):
				print "%s has no attr %s" %(`obj`, a)
				raise AssertionError

	def add_type(self, t):
		if t not in self.types: self.types.append(t)

	def add_class(self, c):
		if c not in self.classes: self.classes.append(c)

	def add_sub(self, s):
		if s not in self.subs: self.subs.append(s)

	def add_attr(self, m):
		if m not in self.attrs: self.attrs.append(m)

	def add_obj(self, o):
		if o not in self.objs: self.objs.append(o)

	def add_typeof(self, o): self.add_type(type(o))
	def add_classof(self, o): self.add_class(o.__class__)
	def add_attrof(self, o):
		for attr in dir(o):		self.add_attr(attr)

	def __repr__(self): return "Type(%s)" % `self.name`


def require(x, t):
	try:
		assert t.include(x)
	except AssertionError:
		print "%s is not of %s" % (`x`, t)
		raise
	t.satisfiedby(x)

def require_either(x, list):
	for t in list:
		if t.include(x):
			t.satisfiedby(x)
			return
	else:
		print "%s is not of any Type in %s" % (`x`, list)
		raise AssertionError

def require_all(x, list):
	for t in list: require(x,t)


#------------------------------------------------------------------
String = Type("String")
String.add_typeof("")

Integer = Type("Integer")
Integer.add_typeof(1)
Integer.add_typeof(1L)

Number = Type("Number")
Number.add_sub(Integer)

Float = Type("Float")
Float.add_typeof(0.0)
Number.add_sub(Float)

File = Type("File")
File.add_attr("close")

#------------------------------------------------------------------
if __name__ == "__main__":

	def f(x):
		require(x, Number)
		print x*2

	f(1)
	f(2.3)

	def f(x):
		require_either(x, (Number, String))
		print x*2
		
	f("2")

	import sys
	File.add_obj(sys.stdout)
	require(sys.stdout, File)

	require_either("2", (Number, String))
	#require_all("2", (Number, String))



More information about the Python-list mailing list