############################################################################## # # Copyright (c) 2002 Zope Corporation and Contributors. # All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ############################################################################## """Computed attributes based on schema fields $Id: fieldproperty.py 40640 2005-12-07 21:49:43Z srichter $ """ _marker = object() class FieldProperty(object): """Computed attributes based on schema fields Field properties provide default values, data validation and error messages based on data found in field meta-data. Note that FieldProperties cannot be used with slots. They can only be used for attributes stored in instance dictionaries. """ def __init__(self, field, name=None): if name is None: name = field.__name__ self.__field = field self.__name = name def __get__(self, inst, klass): if inst is None: return self value = inst.__dict__.get(self.__name, _marker) if value is _marker: field = self.__field.bind(inst) value = getattr(field, 'default', _marker) if value is _marker: raise AttributeError(self.__name) return value def __set__(self, inst, value): field = self.__field.bind(inst) field.validate(value) if field.readonly and inst.__dict__.has_key(self.__name): raise ValueError(self.__name, 'field is readonly') inst.__dict__[self.__name] = value def __getattr__(self, name): return getattr(self.__field, name)