I have a specialist "Instructors". It holds a rack, containing DataSkin-derived ZClasses of meta-type "Instructor". The Instructor class has a DataSkin Attribute propertysheet called "Basic", and this has properties for forename, surname, address, areas. I have some skinscript in the Instructors specialist: WITH SELF COMPUTE name='%s %s' % (forename, surname), areas_comma_sep=_.string.join(areas, ','), address_lines=_.string.join(address, '\n'), address_comma_sep=_.string.join(address, (', ')) WITH SELF COMPUTE __roles__=_.None # XXX publicly visible!! Nutter!! # change __roles__ to ('Operator',) later. This works fine. The __roles__ bit is a hack to make Zope 2.3 ZCatalog play nicely with the Specialist and __bobo_traverse__. I have some other skinscript that keeps an instructors index in a ZCatalog inside Instructors. WHEN OBJECT ADDED CALL Catalog.catalog_object(self, _.string.join(self.getPhysicalPath(),'/')) WHEN OBJECT DELETED CALL Catalog.uncatalog_object(_.string.join(self.getPhysicalPath(),'/')) WHEN OBJECT CHANGED CALL Catalog.uncatalog_object(_.string.join(self.getPhysicalPath(),'/')), Catalog.catalog_object(self, _.string.join(self.getPhysicalPath(),'/')) This worked fine. When I changed the first skinscript to make one WITH SELF statement, I got some strange inconsistencies: WITH SELF COMPUTE name='%s %s' % (forename, surname), areas_comma_sep=_.string.join(areas, ','), address_lines=_.string.join(address, '\n'), address_comma_sep=_.string.join(address, (', ')), __roles__=_.None On changing an instructor's properties using manage_changeProperties on its propertysheet, I'd see the change in the instructor. However, the ZCatalog metadata would always have the most recent value for "surname", but the last value for "name". Changing the skinscript back to using two statements makes cataloging function normally again. I could tell when the catalog was doing by instrumenting the recordify method of Catalog.py: def recordify(self, object): """ turns an object into a record tuple """ print "recordify %s" % (object) record = [] # the unique id is allways the first element for x in self.names: try: attr = getattr(object, x) if(callable(attr)): attr = attr() except: attr = MV print " appending %s:%s" % (x, attr) record.append(attr) return tuple(record) A typical (wrong) debug output would be: recordify <Instructor instance at 86c16b0> appending id:instructor-977678608 appending meta_type:Instructor appending bobobase_modification_time:2001/01/04 17:26:01.35408 GMT appending name:Bob Collins8 appending surname:Collins9 appending areas_comma_sep:M12 This is after changing the surname of the instructor from "Collins8" to "Collins9". The cause of the problem? I don't know. Maybe I'm doing something silly. I think what is happening in the broken example is that when the zope security machinery asks for __roles__, name is also computed. The machinery must request __roles__ before changing anything. After that, surname gets changed. However, changing "surname" only invalidates "surname" in the cache; not anything that is computed using surname. At the end of the transaction, when the triggers are called, name is already in the dataskin's attribute cache, so it does not get recomputed. In the working example, when __roles__ is requested, it is in a different skinscript statement, so it does not cause "name" to be computed. Thus, "name" can be computed freshly after "surname" is set. Is this behaviour intended, is it a bug, or is it an unimplemented feature? Thanks. Oh, almost forgot: ZPatterns-0-4-3b2 -- Steve Alexander Software Engineer Cat-Box limited http://www.cat-box.net I