__getattr__ / __setattr__ - infinite recursion!?

Warren Postma embed at geocities.com
Mon Mar 27 19:03:42 CEST 2000


Okay my first attempt at a "static type checking object" for Python blows
up, probably
a stack overflow, probably due to infinite recursion or some such thing....

Python blows up on the line that instantiates this object! I suspect I'm too
clueless to know how to do a proper __getattr__ / __setattr__
implementation. A better solution to this would be a built in dictionary
type with type-information as part of it's C code.  Has anyone built such a
beast directly in C?

Warren


#---------------------------------------------------------------------
# Why does this blow up Python?
#---------------------------------------------------------------------

import os, sys, string, pprint

# "type objects"
int_type       = type(0)
string_type    = type("X")
float_type     = type(0.1)

# required field flags?
required = 1
optional = 0


# Class with strict type checking and a single key:
class zdb_rec:
    def __init__(self, pattern_dict=None, keyname=None):
        "create an object with a strict pattern of required values to make
up a type"
        self.set_valid(pattern_dict)
        self.keyname = keyname
        self.reset_to_defaults(self)

    def set_valid(self,pattern_dict):
        self.attrs = pattern_dict

    def set_keyname(self,keyname):
        self.keyname = keyname

    def reset_to_defaults(self):
        # fill in default values for each attribute
        self.values = {}
        for x in self.attrs.keys():
            self.values[x] = self.attrs[x][2]

    def keyname(self):
        return self.keyname

    def key(self):
        return self.values[self.keyname]

      # setattr does typesafety check:
    def __setattr__(self,name,value):
        "custom __setattr_ with typesafety check"
        try:
            if (value == None) and (not self.attrs[name][1]):
                self.values[name] = None
            else:
                if (type(value) == self.attrs[name][1]):
                    self.values[name] = value
                else:
                    raise Error, "Invalid type in assignment"+`type(value)`
        except:
            raise Error, "Invalid attribute "+`name`
    def __getattr__(self,name):
        try:
            return self.values[name]
        except:
            raise Error, "Invalid attribute "+`name`

    def attr_count(self):
        return len(self.attrs)

    def validate(self):
        "raises an exception if validation fails, ie requird field not
provided"
        for x in self.attrs.keys():
            if self.attrs[x][1]:
                if self.values[x] == None:
                    raise Error, "validate() failed - required field not
set"

# "Person Database Schema":
person_attributes = {
 # attribute    type          required?   initialvalue
     "name":    (string_type,    required,  ""),
     "address": (string_type,    required,  ""),
     "age":     (int_type,       required,  0 ),
}


x = zdb_rec(person_attributes,"name")

print "done"







More information about the Python-list mailing list