At 03:18 PM 5/17/00 -0400, Dan L. Pierson wrote:
>I'm trying to port the PTK PersistentUserSource stuff to the new
>LoginManager. A lot of things seem to be working, but I seem to have
>fallen into a Catch 22:
>1. UserSources.BasicUserSource defines self._defaultClass as LoginUser, where
>UserSources.LoginUser is a simple RackMountable class (not a ZClass)
>defined earlier in the file.
>2. PTK requires DemoPortal.LoginMember, a ZClass that inherits from
>LoginUser and PersistentUserSource.MemberMixin (actually, it's having
>the MemberMixin stuff that's crucial).
>3. Rack._v_itemConstructor is a ComputedAttribute that looks at
>self._defaultClass: if it's a class, it uses it, if it's a string it
>looks in Products.meta_classes[self._defaultClass] for the class to
getattr(self, '_zclass', None) or self._defaultClass
So as to look for a self._zclass attribute first. _defaultClass is a
>So PersistentUserSource needs to change _defaultClass to refer to
>DemoPortal.LoginMember. If I try to do it by using a
> def _defaultClass(self):
> c = Products.DemoPortal.LoginMember
> self._defaultClass = c
> _defaultClass = ComputedAttribute(_defaultClass)
Don't use a computed attribute; it won't help you as computed attributes
run without acquisition context. This is why _v_defaultItemConstructor
wants to have either an actual ZClass reference, or a string that can be
looked up in the Python-level registries.
>I get an error traceback from an AttributeError in Rack.createItem for
>_v_itemConstructor. BTW: this also happens if I also define
>_v_itemConstructor as a ComputedAttribute in PersistentUserSource. I
>need something like ComputedAttributes here, because DemoPortal
>doesn't (necessarily?) exist at the time PTKDemo is installed.
Oops. Well, that could be a problem. Here's a question, though. Why does
the default class need to be LoginMember? Can't you just set that when you
actually create the UserSource?
>If I try to do it by setting _defaultClass to 'LoginMember', it fails
>because 'LoginMember' isn't in Products.meta_classes. In fact nothing
>relating to DemoPortal or any other ZClass product is in
>Products.meta_classes! The official way to get into that dictionary
>appears to be to call registerBaseClass or registerZClass.
>registerZClass would seem like the correct method, but the ONLY call
>of this is in Products/OFSP/__init__.py for
>ZClasses.ObjectManager.ZObjectManager. Should ZClass products be
This is a limitation of using ComputedAttribute for
_v_defaultItemConstructor, which is why manage_setStorage looks up the
ZClass in the main ZClass registry, and then sets _zclass to point to it.
>If I try to set _defaultClass in PersistentUserSource.__init__. I
>can't figure out how to refer to
>/Control_Panel/Products/DemoPortal/LoginMember from there.
You can't do it from __init__, and you don't want to, anyway, because
__init__ doesn't have acquisition context. It needs to be in
manage_afterAdd and it needs to check whether self._zclass is already set.
If not set, then it should call self.manage_setStorage(zclass='meta type
you want'). Something like:
if not hasattr(self,'_zclass'):
The above assumes the meta_type is 'LoginMember'; you should change it if
Sorry for your pain; the _v_itemConstructor is a bit of a hack. I could
probably fix this by double-layering ComputedAttributes so that it has
acquisition context when it maps from a string to a ZClass.
[pause as I hack, implement, test...]
Here's a patch that works for me (as in it doesn't break other uses of
Rack, I don't know if it'll fix your problem). Try setting _defaultClass
to the string representing the meta_type you want, and see if it works.
The patch changes things to use a double-layered ComputedAttribute so
_v_itemConstructor is called in acquisition context. It also now only sets
self._zclass to a meta_type, instead of referencing the ZClass directly.
The combination should make it possible to use a string for _defaultClass
that refers to a ZClass which is not registered from Python. If it doesn't
work, try my other suggestion(s) above, but this is probably the best way
to fix it.
RCS file: /u/idsuser/REPOSITORY/ZProducts/ZPatterns/Rack.py,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -r1.45 -r1.46
--- Rack.py 2000/05/05 16:44:24 1.45
+++ Rack.py 2000/05/17 21:20:24 1.46
@@ -185,7 +185,7 @@
if type(c) is type(''):
- c = Products.meta_classes[c]
+ c = self._unifiedZClassRegistry()[c]
raise TypeError, "No ZClass set - please use 'Storage' tab"
@@ -195,9 +195,8 @@
self._v_itemConstructor = c
- _v_itemConstructor = ComputedAttribute(_v_itemConstructor)
+ _v_itemConstructor = ComputedAttribute(lambda
def _RawItem(self, key):
Create an empty object of the right class
@@ -346,12 +345,12 @@
if zclass is not None:
- if Products.meta_classes.has_key(zclass):
+ #if Products.meta_classes.has_key(zclass):
self._zclass = zclass
- self._zclass = self._unifiedZClassRegistry()[zclass]
- if hasattr(self,'_v_itemConstructor'):
- del self._v_itemConstructor
+ # self._zclass = self._unifiedZClassRegistry()[zclass]
+ if self.__dict__.has_key('_v_itemConstructor'):
+ del self._v_itemConstructor
raise NameError,("Invalid/nonexistent ZClass '%s'" % zclass)
Zope-Dev maillist - [EMAIL PROTECTED]
** No cross posts or HTML encoding! **
(Related lists -