Re: [Zope3-Users] Re: Can I use IPython in debugzope stuff ?
Never knew about IPython and really like what I see. Thanks for the hint. I got the debugging to work for Zope3 with the following simple change to the tutorial. IPython.Shell.IPShell(user_ns=locals()).mainloop(sys_exit=1) to IPython.Shell.IPShell(user_ns={'root': root, 'app': app}).mainloop(sys_exit=1) Mats On Wed, 10 Jan 2007 18:17:08 +0100, Philipp von Weitershausen wrote KLEIN Stéphane wrote: Can I use IPython in debugzope stuff ? http://wiki.zope.org/zope2/DebuggingWithIPythonAndOtherTips Should work on Zope 3 as well. -- http://worldcookery.com -- Professional Zope documentation and training 2nd edition of Web Component Development with Zope 3 is now shipping! ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Access request object from content_factory
Ooops that should be page for="">zope.app.container.interfaces.IAdding name=AddContent.html class=.forms.MyContentAddForm permission=zope.ManageContent / Mats On Tue, 20 Jun 2006 23:37:35 -0500, mats.nordgren wrote John, I have never done it with the addform approach but it is very easily done with formlib. class MyContentAddForm(form.AddForm): form_fields = form.Fields(IMyContent) def __init__(self, context, request): self.context = context self.request = request def create(self, data): mycontent = MyContent() mycontent.title = data['title'] mycontent.user = self.request.principal.id return mycontent Register it as a page in your config file page for="" name=AddContent.html class=.forms.MyContentAddForm permission=zope.ManageContent / Cheers, Mats On Tue, 20 Jun 2006 22:42:18 +0100 (BST), John Smith wrote Hi, I am trying to add some request related data into a content object (eg authenticated user etc). The content is being added using a normal addform/content_factory zcml approach. The class __init__ method does not receive any arguments, and the context/request pair are only available inside of views. So I am stumped. How do I get at the request object? A utility? An adaptor? Thanks, John Try the all-new Yahoo! Mail . The New Version is radically easier to use The Wall Street Journal ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] WingIDE and debugging Zope3.3
I've tried to get WingIDE to work for debugging Zope3 but have only had limited success. I've followed the instructions at wingware.com where it tells you to add the wingdbstub. I added 'import wingdbstub' in $ZOPEINSTANCE/bin/runzope and it will break on errors but will not break on breakpoints. Other instructions tells you to make sure there is only _one_ thread, and I finally found a setting in zope.app.twisted.schema.xml where I changed it to key name=threads datatype=integer default=1 == Changed to 1 description The number of threads which should be used to serve requests. The threads are placed in a pool and are used to serve requests received from the servers configured using lt;servergt; sections. This does not constrain the total number of threads used by the application server; additional threads may be used for internal purposes. /description /key Still no success. Has anyone had any success with debugging with WingIDE? Sincerely, Mats ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
[Zope3-Users] Dict Widget
I'm totally clueless as how to get a dict widget to work. class IMyObject(Interface): mydict = Dict( title=u'My Dict', key_type=TextLine(), value_type=Int()) I see in zope.app.form.browser the config file has no view defined for IDict and ?IField?. Is it just a matter of configuring a view or do I also need to make a custom widget. Any help appreciated, Mats ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Assigning roles to principals
Marco, You need to pass the id not the principal object. principalRoleManager.getRolesForPrincipal(self.request.principal.id) Cheers, Mats On Wed, 14 Jun 2006 20:00:40 +0200, Marco Mariani wrote How do I get the list of roles for the current principal? I've tried from zope.app.securitypolicy.principalrole import principalRoleManager principalRoleManager.getRolesForPrincipal(self.request.principal) and the list is empty I'm currently defining principals in principals.zcml tnx ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] list woes
I'm not sure this is it or not but FieldProperty doesn't play nice with the persistent list and dict, it will only accept the non persistent list. class ITest(Interface): ... mylist = List(title=u'My List') ... class Test(Persistent): ... implements(ITest) ... mylist = FieldProperty(ITest['mylist']) ... test = Test() test.mylist = PersistentList() ... WrongType: ([], type 'list') test.mylist = list() test.mylist [] Instead of using FieldProperty, try to define it directly as a PersistentList and see if that solves the problem. Cheers, Mats On Wed, 14 Jun 2006 20:16:57 +0200, Marco Mariani wrote Marco Mariani wrote: This creates the gadgets (one per each toy) but the Gadget.name attributes, altough being created, are not persisted. I'd like to understand if what I was trying to do with my objects should just work, or if I misunderstood something. tnx ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] How do I get formlib to play nice with NameChooser
Never mind it was a user error on my part. I was stuffing the data variables in the create function into the context not the object being created. Oooops :) On Fri, 26 May 2006 13:02:42 -0500, mats.nordgren wrote I've been trying to use NameChooser with formlibs AddForm and it always tells me An empty name was provided. Names cannot be empty. I suspect it has to do with set_before_add as my object comes in to the NameChooser without data. Problem is that you define formlib forms with page and set_before_add is in addform. Anyone got this to work? Sincerely, Mats ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Maintaining data fields on form edit
This seems to work class EditForm(form.EditForm): form_fields = form.Fields(ISchema) def __init__(self, context, request): self.context, self.request = context, request @form.action('Edit') def handle_edit_action(self, action, data): if data['image'] != None: self.context.image = data['image'] # continue adding values to context for other fields Cheers, Mats On Wed, 24 May 2006 22:46:37 +0100, Graham Stratton wrote I'm using formlib to create an edit form for a schema which contains a bytes field (an image). When the form is submitted, I don't want the image to be removed if no new image is uploaded. I can't see a simple way to achieve this, but I'm hoping I'm missing something. Many thanks, Graham ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
RE: [Zope3-Users] How to use catalog.searchResults
(Pdb) catalog.searchResults(AbbreviationIndex = ABC) *** TypeError: ('two-length tuple expected', 'ABC') (Pdb) catalog.searchResults([AbbreviationIndex ,ABC]) *** TypeError: searchResults() takes exactly 1 argument (2 given) (Pdb) res = catalog.searchResults() (Pdb) res == None True How to use it? Have you tried catalog.searchResults(idx=('AbbreviationIndex', 'ABC')) Sincerely, Mats ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] How to use catalog.searchResults
My bad, should be catalog.searchResults(AbbreviationIndex=('ABC', 'ABC') Field indices expect a high and low as Alen stated Sincerely, Mats On Sun, 21 May 2006 18:49:46 +0200, Florian Lindner wrote Am Sonntag, 21. Mai 2006 17:58 schrieb mats.nordgren: (Pdb) catalog.searchResults(AbbreviationIndex = ABC) *** TypeError: ('two-length tuple expected', 'ABC') (Pdb) catalog.searchResults([AbbreviationIndex ,ABC]) *** TypeError: searchResults() takes exactly 1 argument (2 given) (Pdb) res = catalog.searchResults() (Pdb) res == None True How to use it? Have you tried catalog.searchResults(idx=('AbbreviationIndex', 'ABC')) Do you mean idx as a placeholder for something or really idx? it gives: (Pdb) results = catalog.searchResults(idx=('AbbreviationIndex', 'ABC')) *** KeyError: 'idx' Regards, Florian ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] ForbiddenAttribute
Look at form.txt in the formlib directory. On Wed, 17 May 2006 11:24:43 -0500, Jachin Rupe wrote hi there thanks for the help. I was just reading somewhere that formlib is the way to go. Is that the general consensus? The problem is, it doesn't look like formlib is covered in either of my books. Does anyone know of any good examples, howtos, tutorials, etc on it's use? I did find this, which may be enough to get me started but I'm thinking more would be better: http://www.romanofski.de/news?currentmonth=11currentyear=2005 -jachin On May 16, 2006, at 9:23 PM, [EMAIL PROTECTED] [EMAIL PROTECTED] wrote: Hi Jachim [...] ForbiddenAttribute: ('street', simple_abook.entry.ABookEntry instance at 0x3afa828) [...] class ABookEntryEditView(EditView): __used_for__ = IABookEntry streetAddress_widget = CustomWidgetFactory(ObjectWidget, ABookEntry) Try to use a formlib form with a correct setup. Or check this part: streetAddress_widget = CustomWidgetFactory(ObjectWidget, ABookEntry) The error above tells you that you try to access the street attribute on the ABookEntry instance. But your interfaces describes that the IStreetAddress implementation which is stored under the streetAddress provides this attribute. So I guess there is a problem with the custom widget factory setup. The rest so far seems Ok to me. Regards Roger Ineichen ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Composing content objects
line 23, in IWorkspace value_type=Object(title=uObject, description=uadsf), in zope/schema/_field.py class Object(Field): __doc__ = IObject.__doc__ implements(IObject) def __init__(self, schema, **kw): you need to pass a schema as a non key-word if not IInterface.providedBy(schema): raise WrongType Sincerely, Mats Nordgren ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Formlib and invariants?
Bernd, That took care of it. Thanks a million. Mats On Thu, 4 May 2006 05:51:52 +0200, Bernd Dorn wrote yes, this should really be fixed up in the default implementation of formlib because interface.Invalid has no registered multiadapter to zope.app.form.browser.interfaces.IWidgetInputErrorView you have to raise a WidgetInputError an example for such an error: from zope.schema import Datetime,Bool,ValidationError from zope.app.form.interfaces import IWidgetInputError class FromGreaterThanTo(ValidationError): uFrom-Date is after To-Date # this is needed to adapt to a view for formlib implements(IWidgetInputError) On 03.05.2006, at 20:59, mats.nordgren wrote: I'm trying to do a join form with formlib and are getting errors when checking invariants. I have my form interface IJoinForm class IJoinForm(Interface): a join form username = schema.TextLine( title=_('User Name'), required=True) password = schema.Password( title=_('Password')) password_check = schema.Password( title=_('Enter Password Again')) title = schema.TextLine( title=_('Title')) @invariant def checkPasswords(obj): if obj.password != obj.password_check: raise Invalid(Passwords do not match) And then I have my implementation of form.Form: class JoinMetroSite(form.Form): form_fields = form.Fields(IJoinForm) @form.action('Join') def handle_join_action(self, action, data): principal_folder = zapi.getUtility(IAuthenticatorPlugin, 'principal') principal = InternalPrincipal(data['username'], data ['password'], data['title']) principal_folder[data['username']] = principal My form in registered with: page for=* class=.metrositeforms.JoinMetroSite name=join.html permission=zope.View menu=zmi_views title=Join / When I try the join.html form I get the following error: Traceback (innermost last): Module zope.publisher.publish, line 138, in publish result = publication.callObject(request, object) Module zope.app.publication.zopepublication, line 161, in callObject return mapply(ob, request.getPositionalArguments(), request) Module zope.publisher.publish, line 113, in mapply return debug_call(object, args) - __traceback_info__: security proxied zope.app.publisher.browser.viewmeta.JoinMetroSite instance at 0x034C9B50 Module zope.publisher.publish, line 119, in debug_call return object(*args) Module zope.formlib.form, line 739, in __call__ return self.render() Module zope.formlib.form, line 733, in render self.form_result = self.template() Module zope.app.pagetemplate.viewpagetemplatefile, line 83, in __call__ return self.im_func(im_self, *args, **kw) Module zope.app.pagetemplate.viewpagetemplatefile, line 51, in __call__ sourceAnnotations=getattr(debug_flags, 'sourceAnnotations', 0), Module zope.pagetemplate.pagetemplate, line 117, in pt_render strictinsert=0, sourceAnnotations=sourceAnnotations)() Module zope.tal.talinterpreter, line 277, in __call__ self.interpret(self.program) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 878, in do_defineMacro self.interpret(macro) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 926, in do_extendMacro definingName, extending) Module zope.tal.talinterpreter, line 908, in do_useMacro self.interpret(macro) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 538, in do_optTag_tal self.do_optTag(stuff) Module zope.tal.talinterpreter, line 523, in do_optTag return self.no_tag(start, program) Module zope.tal.talinterpreter, line 518, in no_tag self.interpret(program) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 878, in do_defineMacro self.interpret(macro) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 976, in do_defineSlot self.interpret(block) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 966, in do_defineSlot self.interpret(slot) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 878, in do_defineMacro self.interpret(macro) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module
[Zope3-Users] Formlib and invariants?
I'm trying to do a join form with formlib and are getting errors when checking invariants. I have my form interface IJoinForm class IJoinForm(Interface): a join form username = schema.TextLine( title=_('User Name'), required=True) password = schema.Password( title=_('Password')) password_check = schema.Password( title=_('Enter Password Again')) title = schema.TextLine( title=_('Title')) @invariant def checkPasswords(obj): if obj.password != obj.password_check: raise Invalid(Passwords do not match) And then I have my implementation of form.Form: class JoinMetroSite(form.Form): form_fields = form.Fields(IJoinForm) @form.action('Join') def handle_join_action(self, action, data): principal_folder = zapi.getUtility(IAuthenticatorPlugin, 'principal') principal = InternalPrincipal(data['username'], data['password'], data['title']) principal_folder[data['username']] = principal My form in registered with: page for=* class=.metrositeforms.JoinMetroSite name=join.html permission=zope.View menu=zmi_views title=Join / When I try the join.html form I get the following error: Traceback (innermost last): Module zope.publisher.publish, line 138, in publish result = publication.callObject(request, object) Module zope.app.publication.zopepublication, line 161, in callObject return mapply(ob, request.getPositionalArguments(), request) Module zope.publisher.publish, line 113, in mapply return debug_call(object, args) - __traceback_info__: security proxied zope.app.publisher.browser.viewmeta.JoinMetroSite instance at 0x034C9B50 Module zope.publisher.publish, line 119, in debug_call return object(*args) Module zope.formlib.form, line 739, in __call__ return self.render() Module zope.formlib.form, line 733, in render self.form_result = self.template() Module zope.app.pagetemplate.viewpagetemplatefile, line 83, in __call__ return self.im_func(im_self, *args, **kw) Module zope.app.pagetemplate.viewpagetemplatefile, line 51, in __call__ sourceAnnotations=getattr(debug_flags, 'sourceAnnotations', 0), Module zope.pagetemplate.pagetemplate, line 117, in pt_render strictinsert=0, sourceAnnotations=sourceAnnotations)() Module zope.tal.talinterpreter, line 277, in __call__ self.interpret(self.program) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 878, in do_defineMacro self.interpret(macro) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 926, in do_extendMacro definingName, extending) Module zope.tal.talinterpreter, line 908, in do_useMacro self.interpret(macro) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 538, in do_optTag_tal self.do_optTag(stuff) Module zope.tal.talinterpreter, line 523, in do_optTag return self.no_tag(start, program) Module zope.tal.talinterpreter, line 518, in no_tag self.interpret(program) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 878, in do_defineMacro self.interpret(macro) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 976, in do_defineSlot self.interpret(block) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 966, in do_defineSlot self.interpret(slot) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 878, in do_defineMacro self.interpret(macro) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 878, in do_defineMacro self.interpret(macro) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 976, in do_defineSlot self.interpret(block) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 878, in do_defineMacro self.interpret(macro) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 538, in do_optTag_tal self.do_optTag(stuff) Module zope.tal.talinterpreter, line 523, in do_optTag return self.no_tag(start, program) Module zope.tal.talinterpreter, line 518, in no_tag self.interpret(program) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 872, in
Re: [Zope3-Users] understanding security
Achim, Take a look at homefolder in the trunk. You can find it here: http://svn.zope.org/Zope3/trunk/src/zope/app/homefolder/ It does what you want to do. On Fri, 07 Apr 2006 16:50:50 +0200, Achim Domma wrote Frank Burkhardt wrote: Do I understand it right, that I do not grant a permission to a principal on a certain object instance? I only grant a permission to use a certain interface!? You can either grant permissions to principals (or groups/roles) globally. Those permissions can be used in multiple ways: * To protect Views. You can only access views you have permissions for (e.g. browser:page ... ) * To protect attributes/methods of classes (*not objects*) (class ...required interface=...) * To define, who is allowed to modify certain attributes (class ...required set_schema=... ) I can follow to this point. That's how I understand Zope security until now. Additionally you may grant permissions (and role memberships) on a per object (*not per class*) basis ( using e.g. the grant.html-View) which effects only a single object. That's what I was looking for, but don't know how to do. For I example: I want to let a user create an object (i.e. a message in a message board). All users with a certain role (i.e. Admins) should be able to edit the new object, but the creating user should also be able to edit it. So I have to give him the persmission to edit. How can I do something like that? regards, Achim ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] Seeking Reference Guide on TAL/TALES/METAL
I think the answer to that question is both, but X['Y'] seem to have precedents over X.Y. class MyContainer(OOBTree): title=u'' class MyContent(Persistent): title=u'' Adding MyContent in MyContainer you can traverse MyContainer/MyContent/title or you can traverse MyContainer/title equally well. If I name MyContainer 'title' i get MyContent when I try MyContainer/title. Sincerely, Mats On Fri, 31 Mar 2006 07:49:44 -0600, Jeff Rush wrote I've been searching and haven't managed to find the definitive reference guide for the particular dialect of TAL/TALES/METAL that is bundled with Zope 3. There are various fragmentary and somewhat divergent documents around and little about how the particular TALES namespaces provided by Zope 3 work in complex cases. http://www.zope.org/Wikis/DevSite/Projects/ZPT/TAL%20Specification%201.4 http://www.zope.org/Wikis/DevSite/Projects/ZPT/TALES%20Specification%201.3 There are no .txt ReST documents under the TAL and TALES source directories, nor anything in the very nice ++APIDOC++ guide. --- My specific question is how evaluation of the path expression X/Z is handled. It *seems* to be: X.__getitem__('Y')# X['Y'] whereas I'm trying to get: X.__getattr__('Y')# X.Y Under Zope 2, as I recall, it would try several algorithms; attribute, mapping, sequence. And I'm wondering if that mechanism was simplified for Zope 3, and in what way. -Jeff ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users
Re: [Zope3-Users] set_before_add
On Fri, 14 Oct 2005 16:36:45 +0200, gnotari wrote On Fri, 14 Oct 2005 15:36:09 +0200, gnotari wrote I'm at loss: I'm replicating the example at cap. 14.3 of Philipp's (Worldcookery) book. It's all about auto-assigning names to object being added to containers. After much tinkering, it does seem to me that this directive browser:addform ... ... set_before_add=id is not working at all. I throughly checked my NameChooser derived class, and verified it works if I make it return some static name. But if I set my NameChooser to use the new object's id attribute (as per example) and try to Add the object, I'm not asked for the id and immediately get the error An empty name was provided. Names cannot be empty. I just tried to have Zope auto assign the name of an object taking the TextLine field 'title' as name. It worked just fine. Remember NameChooser has to be implemented on the container, not the object. The set_before_add should be added to the addform of the object itself. I wrote a small howto on NameChooser at http://counterfate.servebeer.com Replace the part in the chooseName function with: if not name: name = object.id return name Sorry, but it does not solve. I checked your code, and indeed I implemented the same way. Indeed, my code works if I make it generate arbitrary names. It just does not work if I try to name a new object after one of its attributes because: - the attribute value is not set at the time the object is created - I cannot have the add menu ask for it before actually adding (this is what set_before_add should be meant for, I suppose) Just for info, I'm using Zope 3.1. I'm open to any other suggestion as to how have my contained objects (books) be added with thei ISBN code as name in their container. thanks Guido Guido, Yes, I get the same when using 'id' as field name. If I specify a value of id in my implementation, Class SimpleObject(Persistent): implements(ISimpleObject) id = u'NewID' ... it adds the object directly without giving me the addform. Not sure why it does this. Sounds like this is a case for the gurus. Sorry I can't be of more assistance. gnosis ___ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users