[Zope-CMF] Odd behavior with lazy ActionInfo evaluation in CMF 1.5
Alec Mitchell
apm13 at columbia.edu
Thu Jun 30 12:11:32 EDT 2005
Hello all,
I've noticed something odd when viewing the Plone 2.1 (CMF-1.5 branch)
front-page as Anonymous. The 'user' action 'join' defined in
portal_registration gives as it's url 'http://mysite/test_site/join_form', as
expected. The same action when retrieved again in 'portlet_login' gives
'http://mysite/test_site/<function _getURL at 0x40fa102c>', which is
obviously a problem.
I've done a little hand debugging to attempt to figure out how this happens,
and have found the following:
1) On page view, 'global_defines.pt' is called from main_template and defines
the 'action' structure using a call to
portal_actions.listFilteredActionsFor(here).
2) This creates the lazily mapped ActionInfo object for the 'join' action from
the 'join' ActionInformation object in portal_registration. At this time
actions['join']['url'] is set to self._getURL, and the key 'url' is added to
the ActionInfo's 'lazy_keys' list.
3) This ActionInfo object, unchanged, is used in the path expression
'action/url' in the loop through user actions in 'global_personalbar.pt'
which is called from main_template.
4) This causes ActionInfo.__getitem__ to be called for 'url' and the _getURL
method is retrieved. Because 'url' is in 'lazy_keys', the method is
evaluated, the the ActionInfo dict is updated with the evaluated value for
'url', and the 'url' entry is removed from 'lazy_keys'.
The above steps are the expected behavior, and appear to work perfectly. The
strange part follows:
5) 'portlet_login' gets the url for the action using "[a['url'] for a in
actions['user'] if a['id']=='join']".
6) This results in another call to ActionInfo.__getitem__ on what should be
the same ActionInfo instance. Again the _getURL method is retrieved, which
is unexpected as that value was replaced with the result of calling the
method in step #4 above. 'lazy_keys' no longer has the entry 'url', so the
method is not evaluated, and the method itself is returned.
Though the ActionInfo for this action is only created once, and the changes
made to it's 'lazy_keys' variable can be seen on subsequent calls to the
instance, it appears that some of the changes to the object are getting lost
between subsequent calls to __getitem__. In fact, I tested setting a new
instance variable during the __getitem__ call, and on the subsequent call
this variable was no longer set!
If these were persistent objects I would attribute this sort of weirdness to
the need for some _p_changed updates or some partial transaction rollback,
but these are simple UserDict subclasses which are never stored in the ZODB.
I've thus far been unable to write a unit test which demonstrates the bug,
but it is easily repeatable. Anybody have an idea what might be going on
here?
Alec
More information about the Zope-CMF
mailing list