[TransWarp] Constraints on model attributes

Roché Compaan roche at upfrontsystems.co.za
Mon Jul 28 17:24:05 EDT 2003

* Phillip J. Eby <pje at telecommunity.com> [2003-07-28 03:36]:
> At 10:33 PM 7/27/03 +0200, Roché Compaan wrote:
> >I started out following the pattern you describe above but as I went
> >along I realised some attributes belong in the feature definition and
> >not in the type definition.
> Judging by your attachment, I'd have to say we disagree quite a bit on 
> which is which.  IMO, your Container, Iterable, Orderable, Enumerable, 
> Bool, Int, and so on are all *types* -- even MinMaxLen.  These are all 
> things that are entirely independent of a structural feature.  (By the way, 
> peak.model offers a built-in enumeration type, as well.)

I refactored all the class that were previously model.Attributes so that
they are now types and so that do proper type checks. I have a small
problem though. Given the following types:

class MinMaxLen(model.Type):
    """ Expresses constraints on the length of a value.
    min_length = 0
    max_length = None

    def mdl_normalize(klass, value):
        super(MinMaxLen, klass).mdl_normalize(value)

        if klass.min_length is not None and len(value) < klass.min_length:
            raise ValueError("Too short", value, klass.min_length)

        if klass.max_length is not None and len(value) > klass.max_length:
            raise ValueError("Too long", value, klass.max_length)

        return value

class Enumeration(model.Enumeration):
    """ Extends Enumeration to raise exception when value is not in
        set of literals.

    def mdl_normalize(klass, value):
        super(Enumeration, klass).mdl_normalize(value)
        values = klass._EnumerationClass__enumeration_values.keys()
        if values and not value in values:
            raise ValueError("Invalid value", value, values)

class Text(Enumeration, MinMaxLen):
    """A field containing text used for human discourse."""

    def mdl_normalize(klass, value):
        super(Text, klass).mdl_normalize(value)
        value = unicode(value)
        return value

How do I set attributes on the referencedType that are needed for
normalization *without* subclassing the types. To be clear, let's
say I have a model.Attribute that only allows values in an enumerated
set and with a maximum length of 4 characters. For example on planet
Stepford, the beings there are only allowed names John, Mary and Pete
and their names may not be longer than 4 characters.

class Drone(model.Element):

    class Name(model.Attribute):
        referencedType = Text

        # Ugly, doesn't work and just to illustrate what I want to do.
        referencedType.max_length = 4
        referencedType.John = model.enum("John")
        referencedType.Mary = model.enum("Mary")
        referencedType.Pete = model.enum("Pete")

        # or
        referencedType = Text(max_length=4, 
            allowed_values=["John", "Mary", "Pete"])

This is where I got stuck previously and implemented what are now types
as model.Attributes.

Roché Compaan
Upfront Systems                 http://www.upfrontsystems.co.za

More information about the PEAK mailing list