More product writing problems
Hello, I want to write my own instance of FOlder product maintaining a set of keywords. This worked so far but I want to strip some spaces from the keywords the user might have prepended/appended. I wanted to use the following code: ob=MyFolder() ob.id=str(id) ob.title=title ob.keywords={} for kw in keywords: kw=kw.strip() if kw != '' : ob.keywords.append(kw) self._setObject(id, ob) ob=self._getOb(id) Well, obviousely this is intended to work under python2.1. Because of a broken Zope 2.4.2 installation which does not show up my product in the products folder mysteriousely (see thread "Problems writing a new product") I use Zope 2.3.3 (Debian/GNU Linux Woody zope_2.3.3-1) which depends from Python 1.5 - at least under my system. If I link /usr/bin/python to /usr/bin/python2.1 zope does not start because of some modules (namely 'os') are not found. So how can I write this code safe even for older Python versions or does anybody has an idea how to fix the broken Zope installation? What other logfiles could I observe. I did not found any others than Z2.log. Kind regards Andreas.
which depends from Python 1.5 - at least under my system. If I link /usr/bin/python to /usr/bin/python2.1 zope does not start because of some modules (namely 'os') are not found.
You need to get Zope to use the 2.1 libraries as well as the 2.1 binary. Make a symlink from Zope/lib/python-2.1 to <python>/lib/python-2.1. seb
On Tue, 4 Dec 2001, Seb Bacon wrote:
You need to get Zope to use the 2.1 libraries as well as the 2.1 binary. Make a symlink from Zope/lib/python-2.1 to <python>/lib/python-2.1. Well, this worked so far with exception of a whole bunch of warnings at restart:
WARNING: Python C API version mismatch for module _OIBTree: This Python has API version 1010, module _OIBTree has version 1007. for several different modules as well as _OIBTree. But this is another problem which I have to sort out. The problem is that I seem to missunderstood the 'type' of my keywords variable: ob=MyFolder() ob.id=str(id) ob.title=title ob.keywords={} for kw in keywords: kw=kw.strip() if kw != '' : ob.keywords.append(kw) self._setObject(id, ob) ob=self._getOb(id) now has the following problem: Import Traceback Traceback (most recent call last): File "/usr/lib/zope/lib/python/OFS/Application.py", line 528, in import_products product=__import__(pname, global_dict, global_dict, silly) File "/usr/lib/zope/lib/python/Products/MyFolder/__init__.py", line 1, in ? from MyFolder import MyFolder, manage_addMyFolderForm, manage_addMyFolder File "/usr/lib/zope/lib/python/Products/MyFolder/MyFolder.py", line 63 ob.keywords.append() = kw SyntaxError: can't assign to function call My 'keywords' variable is a set of lines and I want to store each single line as one keyword. Does anybody know how to do that. Sorry, I'm a bloody Python beginner. Kind regards Andreas.
----- Original Message ----- From: Tille, Andreas <TilleA@rki.de>
WARNING: Python C API version mismatch for module _OIBTree: This Python has API version 1010, module _OIBTree has version 1007.
Means just want it says: the modules were compiled with a different python from the one you're using. Normally shouldn't matter.
ob.keywords={} for kw in keywords: kw=kw.strip()
You can't iterate over a dictionary. It doesn't have a order, and it is made up of key, value pairs. You want for kw in keywords.keys(): # do stuff value = keywords[key] # for example Actually, I think python 2.1 or perhaps 2.2 adds some new methods to dictionaries but I can't remember what. seb
On Tue, 4 Dec 2001, Seb Bacon wrote:
Means just want it says: the modules were compiled with a different python from the one you're using. Normally shouldn't matter.
ob.keywords={} for kw in keywords: kw=kw.strip()
You can't iterate over a dictionary. It doesn't have a order, and it is made up of key, value pairs. You want for kw in keywords.keys(): # do stuff value = keywords[key] # for example
Actually, I think python 2.1 or perhaps 2.2 adds some new methods to Sorry, I did not described my problem exactly. My problem is perhaps that I do not know *which* is the correct type of my variable keywords. (Sorry, I'm a little bit C-centered where I had to declare each variable.)
I think I post my complete method to clarify: def manage_addMyFolder(self, id, title='', keywords='', #### not sure if this is correct but #### it worked so far createPublic=1, createSelection=1, createHome=1, createUserF=0, REQUEST=None): """Add a new MyFolder object with id *id* and global keywords *keywords* and author *author*. If the 'createPublic' and 'createUserF' parameters are set to any true value, an 'index_html' and a 'UserFolder' objects are created respectively in the new folder. You can specify certain keywords which are inserted into each Document inside this folder. """ ob=MyFolder() ob.id=str(id) ob.title=title ob.keywords=keywords #### this works but I want to remove whitespaces #### and empty lines # for kw in keywords: #### this does not work :-( see below # kw=kw.strip() # if kw != '' : # ob.keywords = ob.keywords + '\n' + kw self._setObject(id, ob) ob=self._getOb(id) checkPermission=getSecurityManager().checkPermission if createUserF: if not checkPermission('Add User MyFolders', ob): raise 'Unauthorized', ( 'You are not authorized to add User MyFolders.' ) ob.manage_addUserFolder() if createPublic: if not checkPermission('Add Documents, Images, and Files', ob): raise 'Unauthorized', ( 'You are not authorized to add DTML Documents.' ) ob.manage_addDTMLDocument(id='index.htm', title=ob.id+' main frame') if REQUEST is not None: return self.manage_main(self, REQUEST, update_menu=1) The problem obviousely is, that I do not know what Python type is appropriate to store the *lines* which are obtained in a <tr valign="top"> <th class="form-optional">Keywords<br>(One per line)</th> <td><textarea name="keywords:lines" cols="50" rows="10"> </textarea> </td> </tr> textarea and how I should strip the whitespaces and empty lines from it. a string variable separated by '\n' does not work either as I tested because if I want to edit them I get: Error Type: InError Error Value: Strings are not allowed as input to the in tag. So the question is: How to strip the whitespace from the keywords correctly. Thanks for your patience Andreas.
Not quite sure what's wrong here. foo:lines should get coerced into a list type. Your default value in the function signature should therefore be keywords=(), rather than keywords=''. But if you're passing a value in, this shouldn't be a problem. Watch out for using the name kw for a variable, since this is the standard name for a dictionary of keyword arguments. seb ----- Original Message ----- From: Tille, Andreas <TilleA@rki.de> Cc: Zope user list <zope@zope.org> Sent: Wednesday, December 05, 2001 8:07 AM Subject: [Zope] Re: More product writing problems
On Tue, 4 Dec 2001, Seb Bacon wrote:
Means just want it says: the modules were compiled with a different python from the one you're using. Normally shouldn't matter.
ob.keywords={} for kw in keywords: kw=kw.strip()
You can't iterate over a dictionary. It doesn't have a order, and it is made up of key, value pairs. You want for kw in keywords.keys(): # do stuff value = keywords[key] # for example
Actually, I think python 2.1 or perhaps 2.2 adds some new methods to Sorry, I did not described my problem exactly. My problem is perhaps that I do not know *which* is the correct type of my variable keywords. (Sorry, I'm a little bit C-centered where I had to declare each variable.)
I think I post my complete method to clarify:
def manage_addMyFolder(self, id, title='', keywords='', #### not sure if this is correct but #### it worked so far createPublic=1, createSelection=1, createHome=1, createUserF=0, REQUEST=None): """Add a new MyFolder object with id *id* and global keywords *keywords* and author *author*.
If the 'createPublic' and 'createUserF' parameters are set to any true value, an 'index_html' and a 'UserFolder' objects are created respectively in the new folder.
You can specify certain keywords which are inserted into each Document inside this folder. """ ob=MyFolder() ob.id=str(id) ob.title=title ob.keywords=keywords #### this works but I want to remove whitespaces #### and empty lines # for kw in keywords: #### this does not work :-( see below # kw=kw.strip() # if kw != '' : # ob.keywords = ob.keywords + '\n' + kw self._setObject(id, ob) ob=self._getOb(id)
checkPermission=getSecurityManager().checkPermission
if createUserF: if not checkPermission('Add User MyFolders', ob): raise 'Unauthorized', ( 'You are not authorized to add User MyFolders.' ) ob.manage_addUserFolder()
if createPublic: if not checkPermission('Add Documents, Images, and Files', ob): raise 'Unauthorized', ( 'You are not authorized to add DTML Documents.' ) ob.manage_addDTMLDocument(id='index.htm', title=ob.id+' main frame')
if REQUEST is not None: return self.manage_main(self, REQUEST, update_menu=1)
The problem obviousely is, that I do not know what Python type is appropriate to store the *lines* which are obtained in a
<tr valign="top"> <th class="form-optional">Keywords<br>(One per line)</th> <td><textarea name="keywords:lines" cols="50" rows="10"> </textarea> </td> </tr>
textarea and how I should strip the whitespaces and empty lines from it. a string variable separated by '\n' does not work either as I tested because if I want to edit them I get:
Error Type: InError Error Value: Strings are not allowed as input to the in tag.
So the question is: How to strip the whitespace from the keywords correctly.
Thanks for your patience
Andreas.
_______________________________________________ Zope maillist - Zope@zope.org http://lists.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope-dev )
On Wed, 5 Dec 2001, Seb Bacon wrote:
Not quite sure what's wrong here. foo:lines should get coerced into a list type.
Your default value in the function signature should therefore be keywords=(), rather than keywords=''. But if you're passing a value in, this shouldn't be a problem. I now seem to have found the solution:
def manage_addMyFolder(self, id, title='', keywords=[], ... ob.keywords=[] for keyword in keywords: keyword=keyword.strip() if keyword != '' : ob.keywords.append(keyword) Anyway, thanks for the hint.
Watch out for using the name kw for a variable, since this is the standard name for a dictionary of keyword arguments. Thanks. As you see I now use a more general variable name.
But as any answer opens a new question: Now I managed to get striped keywords at creation time of my Folder. But if I change the keywords via the properties tab they will not be stripped. I guess I have to rewrite a further method - but which one? Is there any template? Kind regards Andreas.
Now I managed to get striped keywords at creation time of my Folder. But if I change the keywords via the properties tab they will not be stripped. I guess I have to rewrite a further method - but which one?
You could do one of: - hack the propertymanager code - create custom property editing screens which post to a pythonscript, which strips the whitespace before storing it - deal with the whitespace issue inside your product - do a getProperty() method which strips before returning seb
On Wed, 5 Dec 2001, Seb Bacon wrote:
- hack the propertymanager code How far is this different from the latest one?
- create custom property editing screens which post to a pythonscript, which strips the whitespace before storing it Hmm, seems me not as good as the other suggestion, but I might be wrong because of a lack of experience.
- deal with the whitespace issue inside your product - do a getProperty() method which strips before returning I tried to add the following Method to my product:
def getProperty(self, id, d=None): """Get the property 'id', returning the optional second argument or None if no such property is found.""" if self.hasProperty(id): if id == 'keywords' : # + safe_keywords=self.keywords # + self.keywords=[] # + for keyword in save_keywords: # + keyword=keyword.strip() # + if keyword != '' : # + self.keywords.append(keyword) # + return getattr(self, id) return d I took the code crom PropertyManager and added the marked (# +) lines. I'm not sure if I did this right but it does not work as expected. Any idea how to debug such kind of code? (To make sure that there is no other problem I attached the whole code.) Another problem I see is that I want to test in a DTML Document, whether there are keywords defined or not (resp. if I'm in an MyFolder or not). The following just raises just an AttributeError. getattr(object, string) Return the value of the named attributed of object. name must be a string. If the string is the name of one of the object's attributes, the result is the value of that attribute. For example, getattr(x, "foobar") is equivalent to x.foobar. If the named attribute does not exist, default is returned if provided, otherwise AttributeError is raised. How can I do this cleanly? Kind regards and many thanks for your great help Andreas.
On Wed, Dec 05, 2001 at 01:12:45PM +0100, Tille, Andreas wrote:
safe_keywords=self.keywords # + self.keywords=[] # + for keyword in save_keywords: # +
^^^^ You'll get a NameError there because of a misspelling. Earlier you created it as safe_keywords, not save_keywords. -- paul winkler home: http://www.slinkp.com music: http://www.reacharms.com calendars: http://www.calendargalaxy.com
On Wed, 5 Dec 2001, Paul Winkler wrote:
On Wed, Dec 05, 2001 at 01:12:45PM +0100, Tille, Andreas wrote:
safe_keywords=self.keywords # + self.keywords=[] # + for keyword in save_keywords: # +
^^^^ You'll get a NameError there because of a misspelling. Earlier you created it as safe_keywords, not save_keywords. It was not my best day yesterday :).
Many thanks Andreas.
Hello, while now syntactically correct I was not able to solve my logical problem, which is: Stripping a set of keywords of type 'lines' from whitespace and removing blank lines. The properties.dtml method calls 'manage_editProperties:method'. So I searched $(ZOPE_HOME)/lib/python/OFS/PropertyManager.py for this method. This calls 'self._updateProperty(name, value)' and so I've thought it would be sane to override this method with my own. I just copyed the method _updateProperty from and tried def _updateProperty(self, id, value): # Update the value of an existing property. If value # Code was stolen from: /usr/lib/zope/lib/python/OFS/PropertyManager.py # is a string, an attempt will be made to convert # the value to the type of the existing property. self._wrapperCheck(value) if not self.hasProperty(id): raise 'Bad Request', 'The property %s does not exist' % id if type(value)==type(''): proptype=self.getPropertyType(id) or 'string' if type_converters.has_key(proptype): value=type_converters[proptype](value) if id == 'keywords' : # + save_keywords=self.keywords # + self.keywords=[] # + for keyword in save_keywords: # + keyword=keyword.strip() # + if keyword != '' : # + self.keywords.append(keyword) # + else: self._setPropValue(id, value) Unfortunately I see no effect for my changed keyword values. Did I something wrong? Any suggestion how to debug this code? Kind regards Andreas.
Tille, Andreas writes:
while now syntactically correct I was not able to solve my logical problem, which is: Stripping a set of keywords of type 'lines' from whitespace and removing blank lines. ... def _updateProperty(self, id, value): .... # Update the value of an existing property. If value # Code was stolen from: /usr/lib/zope/lib/python/OFS/PropertyManager.py # is a string, an attempt will be made to convert # the value to the type of the existing property. self._wrapperCheck(value) if not self.hasProperty(id): raise 'Bad Request', 'The property %s does not exist' % id if type(value)==type(''): proptype=self.getPropertyType(id) or 'string' if type_converters.has_key(proptype): value=type_converters[proptype](value) if id == 'keywords' : # + save_keywords=self.keywords # + self.keywords=[] # + for keyword in save_keywords: # + keyword=keyword.strip() # + if keyword != '' : # + self.keywords.append(keyword) # + else: self._setPropValue(id, value)
Unfortunately I see no effect for my changed keyword values. Did I something wrong? Any suggestion how to debug this code? You do not use the new value but the current value...
Use "for keyword in value:" instead of "for keyword in save_keywords". Dieter
On Fri, 7 Dec 2001, Dieter Maurer wrote:
def _updateProperty(self, id, value): .... # Update the value of an existing property. If value # Code was stolen from: /usr/lib/zope/lib/python/OFS/PropertyManager.py # is a string, an attempt will be made to convert # the value to the type of the existing property. self._wrapperCheck(value) if not self.hasProperty(id): raise 'Bad Request', 'The property %s does not exist' % id if type(value)==type(''): proptype=self.getPropertyType(id) or 'string' if type_converters.has_key(proptype): value=type_converters[proptype](value) if id == 'keywords' : # + save_keywords=self.keywords # + self.keywords=[] # + for keyword in save_keywords: # + keyword=keyword.strip() # + if keyword != '' : # + self.keywords.append(keyword) # + else: self._setPropValue(id, value)
Use "for keyword in value:" instead of "for keyword in save_keywords". Uhm, there are errors and stupid errors. Thanks for pointing to the stupid error. But unfortunately there seems to be another one, because it does not work even if I use 'value' nor if I change the code to
if id == 'keywords' : new_value=[] for keyword in value: keyword=keyword.strip() if keyword != '' : new_value.append(keyword) value=new_value self._setPropValue(id, value) My suspection is that something goes wrong more generally (the _updateProperty is just not called or the if condition might not be true because any strange pre/or suffixes or something else). So I'm looking for any suggestion how to debug the code efficiently. If I would insert any 'print' statements or something else to which data stream would they directed. Would it be the STUPID_LOG_FILE or something else or should I open a temporary file. Which is the method you use generally for such stuff? Kind regards Andreas.
Tille, Andreas writes:
But unfortunately there seems to be another one, because it does not work even if I use 'value' nor if I change the code to
if id == 'keywords' : new_value=[] for keyword in value: keyword=keyword.strip() if keyword != '' : new_value.append(keyword) value=new_value self._setPropValue(id, value) The code looks good!
My suspection is that something goes wrong more generally (the _updateProperty is just not called or the if condition might not be true because any strange pre/or suffixes or something else).
So I'm looking for any suggestion how to debug the code efficiently. I debug Python code in Zope with adding:
import pdb; pdb.set_trace() When Zope executes this code, it stops and I can use "pdb" (Python's debugger) to analyse the state and single step. Breakpoints do not work, however. It is also not that easy to quit the debugger again. A colleague is using WingIDE, an IDE for Python (and other languages) able to debug Zope applications. He is quite happy with it (it is not free, however). There is a HowTo on zope.org explaining how to debug Zope applications out of [X]Emacs. Probably "Komodo", another IDE for Python and other languages, too, is able to debug Zope applications (not free, too).
If I would insert any 'print' statements or something else to which data stream would they directed. Would it be the STUPID_LOG_FILE or something else or should I open a temporary file. Which is the method you use generally for such stuff? No, they would go to standard output, unless you redirect them with the ">>" operator.
Do not forget to flush your output stream when you use "print". Otherwise, you will be astonished that your output sits in the buffer and you wait in vain... Dieter
andreas, the "cannot find os module" is most likely due to python2.1 claiming the environment variable PYTHONHOME. look in your start scripts to see if it is set anywhere, if it is rename it to something else. jens On Tuesday, December 4, 2001, at 11:20 , Tille, Andreas wrote:
Hello,
I want to write my own instance of FOlder product maintaining a set of keywords. This worked so far but I want to strip some spaces from the keywords the user might have prepended/appended. I wanted to use the following code:
ob=MyFolder() ob.id=str(id) ob.title=title ob.keywords={} for kw in keywords: kw=kw.strip() if kw != '' : ob.keywords.append(kw) self._setObject(id, ob) ob=self._getOb(id)
Well, obviousely this is intended to work under python2.1. Because of a broken Zope 2.4.2 installation which does not show up my product in the products folder mysteriousely (see thread "Problems writing a new product") I use Zope 2.3.3 (Debian/GNU Linux Woody zope_2.3.3-1) which depends from Python 1.5 - at least under my system. If I link /usr/bin/python to /usr/bin/python2.1 zope does not start because of some modules (namely 'os') are not found.
So how can I write this code safe even for older Python versions or does anybody has an idea how to fix the broken Zope installation? What other logfiles could I observe. I did not found any others than Z2.log.
Kind regards
Andreas.
_______________________________________________ Zope maillist - Zope@zope.org http://lists.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope-dev )
participants (5)
-
Dieter Maurer -
Jens Vagelpohl -
Paul Winkler -
Seb Bacon -
Tille, Andreas