##// END OF EJS Templates
Merging latest trunk....
Merging latest trunk. I got a criss-cross merge in this and did merge --weave. Hope this is OK.

File last commit:

r1741:079041c4
r1890:c3323314 merge
Show More
minitraits.py
118 lines | 3.2 KiB | text/x-python | PythonLexer
import types
class AttributeBase(object):
def __get__(self, inst, cls=None):
if inst is None:
return self
try:
return inst._attributes[self.name]
except KeyError:
raise AttributeError("object has no attribute %r" % self.name)
def __set__(self, inst, value):
actualValue = self.validate(inst, self.name, value)
inst._attributes[self.name] = actualValue
def validate(self, inst, name, value):
raise NotImplementedError("validate must be implemented by a subclass")
class NameFinder(type):
def __new__(cls, name, bases, classdict):
attributeList = []
for k,v in classdict.iteritems():
if isinstance(v, AttributeBase):
v.name = k
attributeList.append(k)
classdict['_attributeList'] = attributeList
return type.__new__(cls, name, bases, classdict)
class HasAttributes(object):
__metaclass__ = NameFinder
def __init__(self):
self._attributes = {}
def getAttributeNames(self):
return self._attributeList
def getAttributesOfType(self, t, default=None):
result = {}
for a in self._attributeList:
if self.__class__.__dict__[a].__class__ == t:
try:
value = getattr(self, a)
except AttributeError:
value = None
result[a] = value
return result
class TypedAttribute(AttributeBase):
def validate(self, inst, name, value):
if type(value) != self._type:
raise TypeError("attribute %s must be of type %s" % (name, self._type))
else:
return value
# class Option(TypedAttribute):
#
# _type = types.IntType
#
# class Param(TypedAttribute):
#
# _type = types.FloatType
#
# class String(TypedAttribute):
#
# _type = types.StringType
class TypedSequenceAttribute(AttributeBase):
def validate(self, inst, name, value):
if type(value) != types.TupleType and type(value) != types.ListType:
raise TypeError("attribute %s must be a list or tuple" % (name))
else:
for item in value:
if type(item) != self._subtype:
raise TypeError("attribute %s must be a list or tuple of items with type %s" % (name, self._subtype))
return value
# class Instance(AttributeBase):
#
# def __init__(self, cls):
# self.cls = cls
#
# def validate(self, inst, name, value):
# if not isinstance(value, self.cls):
# raise TypeError("attribute %s must be an instance of class %s" % (name, self.cls))
# else:
# return value
# class OptVec(TypedSequenceAttribute):
#
# _subtype = types.IntType
#
# class PrmVec(TypedSequenceAttribute):
#
# _subtype = types.FloatType
#
# class StrVec(TypedSequenceAttribute):
#
# _subtype = types.StringType
#
#
# class Bar(HasAttributes):
#
# a = Option()
#
# class Foo(HasAttributes):
#
# a = Option()
# b = Param()
# c = String()
# d = OptVec()
# e = PrmVec()
# f = StrVec()
# h = Instance(Bar)