[Zope-dev] ZPatterns; possible bug?
Steve Alexander
steve@cat-box.net
Thu, 04 Jan 2001 18:03:11 +0000
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