Issue 1896: manage_changeProperties() vs manage_addProperty()
Hello, in Issue #1896 (http://www.zope.org/Collectors/Zope/1896), I describe a difference in the behaviour of manage_changeProperties() and of manage_addProperty(): An array of ints is converted to an array of strings with manage_addProperty(), but not with manage_changeProperties(). You closed the bug with the following comment:
Type converters only deal with the outer type but not with the types of contained elements. This should be handled on the application level.
Well, first of all this isn't true as my script shows (note: the report has a buggy test script, correct one attached): When using manage_addProperty(), the contents of the array *are* converted from integers to strings. Or maybe I'm reading you wrong? Furthermore, this still doesn't explain why the two functions behave differently. Digging a bit deeper, I found out that the culprit is in lib/python/OFS/PropertyManager.py: In manage_addProperty() the type_converter is always called, but in _updateProperty() the type_converter is only called if the value is a string. Similar code can be found in lib/python/OFS/PropertySheets.py Maybe there is some reason for this behaviour, but I can't think of one. Either of the following diffs (of course not both!) fixes the problem for me: --- lib/python/OFS/PropertyManager.py.old 2006-06-18 09:56:13.000000000 +0200 +++ lib/python/OFS/PropertyManager.py 2006-06-18 09:57:01.000000000 +0200 @@ -202,16 +202,13 @@ self._setPropValue(id, value) def _updateProperty(self, id, value): - # Update the value of an existing property. If value - # is a string, an attempt will be made to convert - # the value to the type of the existing property. + # Update the value of an existing property. self._wrapperCheck(value) if not self.hasProperty(id): raise BadRequest, 'The property %s does not exist' % escape(id) - if type(value)==type(''): - proptype=self.getPropertyType(id) or 'string' - if type_converters.has_key(proptype): - value=type_converters[proptype](value) + proptype=self.getPropertyType(id) or 'string' + if type_converters.has_key(proptype): + value=type_converters[proptype](value) self._setPropValue(id, value) def _delProperty(self, id): --- lib/python/OFS/PropertyManager.py.old 2006-06-18 09:56:13.000000000 +0200 +++ lib/python/OFS/PropertyManager.py 2006-06-20 12:31:56.000000000 +0200 @@ -265,14 +265,14 @@ # Web interface - def manage_addProperty(self, id, value, type, REQUEST=None): + def manage_addProperty(self, id, value, proptype, REQUEST=None): """Add a new property via the web. Sets a new property with the given id, type, and value. """ - if type_converters.has_key(type): - value=type_converters[type](value) - self._setProperty(id.strip(), value, type) + if type(value)==type('') and type_converters.has_key(proptype): + value=type_converters[proptype](value) + self._setProperty(id.strip(), value, proptype) if REQUEST is not None: return self.manage_propertiesForm(self, REQUEST) This is the working version of my test script: ## Script (Python) "test" ##bind container=container ##bind context=context ##bind namespace= ##bind script=script ##bind subpath=traverse_subpath ##parameters= ##title= ## def is_int(i): try: i + 1 return "is int" except: return "isn't int" obj = script try: obj.manage_delProperties(ids=('testproperty',)) except: pass print "Add property..." obj.manage_addProperty('testproperty', [1,2,3], 'lines') for i in obj.testproperty: print is_int(i) print "Change property..." obj.manage_changeProperties(testproperty=[1,2,3]) for i in obj.testproperty: print is_int(i) return printed Thank you. PS: I know this doesn't seem important, but it gave me a hard to debug problem once.
Berthold Stöger wrote:
Hello,
in Issue #1896 (http://www.zope.org/Collectors/Zope/1896), I describe a difference in the behaviour of manage_changeProperties() and of manage_addProperty(): An array of ints is converted to an array of strings with manage_addProperty(), but not with manage_changeProperties().
You closed the bug with the following comment:
Type converters only deal with the outer type but not with the types of contained elements. This should be handled on the application level.
Well, first of all this isn't true as my script shows (note: the report has a buggy test script, correct one attached): When using manage_addProperty(), the contents of the array *are* converted from integers to strings. Or maybe I'm reading you wrong?
Furthermore, this still doesn't explain why the two functions behave differently. Digging a bit deeper, I found out that the culprit is in lib/python/OFS/PropertyManager.py:
In manage_addProperty() the type_converter is always called, but in _updateProperty() the type_converter is only called if the value is a string. Similar code can be found in lib/python/OFS/PropertySheets.py
Maybe there is some reason for this behaviour, but I can't think of one. Either of the following diffs (of course not both!) fixes the problem for me:
I've reopened the bug. Florent -- Florent Guillaume, Nuxeo (Paris, France) Director of R&D +33 1 40 33 71 59 http://nuxeo.com fg@nuxeo.com
participants (2)
-
Berthold Stöger -
Florent Guillaume