quetz-mod_python-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Anders Blomdell <anders.blomd...@control.lth.se>
Subject Re: Bizarre behaviour in util.FieldStorage
Date Mon, 01 Mar 2010 15:04:15 GMT
Anders Blomdell wrote:
> Hi,
> 
> When a FieldStorage has two (or more) Filed instances with the same value but
> different names, the behaviour of programs like this is (more or less) undefined:
> 
>   fs = util.FieldStorage(req)
>   fs['id1'] = 'New value'
>   del fs['id2']
> 
> The reason for the undefinedness, is this code in __delitem__ (and the similar
> in __setitem__):
> 
>         table = self.list.table()
>         values = table[key]
>         for value in values:
>             self.list.remove(value)
> 
> What happens is that the self.list.remove(value) will remove the first field
> with a matching value, regardless of that fields name. Here is an example from
> real life:
> 
>     form.clear()
>     form['id1'] = 'x'
>     form['id2'] = 'x'
>     form['id3'] = 'x'
>     # Form now contains {'id2': [Field('id2', 'x')],
>     #                    'id3': [Field('id3', 'x')],
>     #                    'id1': [Field('id1', 'x')]}
>     form['id2'] = 'y'
>     # Form now contains {'id2': [Field('id2', 'x'), Field('id2', 'y')],
>     #                    'id3': [Field('id3', 'x')]}
>     # which is not what I would have expected
> 
> 
> In my simple example, one solution, is to add the following method to StringField:
> 
>     def __eq__(self, other):
>         return self.value == other.value and self.name == other.name
> 
> but this does not properly handle mixing Field and StringField. Anybody has a
> better solution?

Some more thinking made me come up with the patch below.

Regards

Anders

--- /usr/lib/python2.6/site-packages/mod_python/util.py.orig        2006-11-22
12:15:54.000000000 +0100
+++ /usr/lib/python2.6/site-packages/mod_python/util.py 2010-03-01
16:00:30.000000000 +0100
@@ -145,6 +145,12 @@
                     self.__table[item.name] = [item]
         return self.__table

+    def delete_name(self, name):
+        self.__table = None
+        for i in range(len(self) - 1, -1, -1):
+            if self[i].name == name:
+                self.pop(i)
+
     def __delitem__(self, *args):
         self.__table = None
         return list.__delitem__(self, *args)
@@ -348,11 +354,8 @@
         self.list.append(item)

     def __setitem__(self, key, value):
-        table = self.list.table()
-        if table.has_key(key):
-            items = table[key]
-            for item in items:
-                self.list.remove(item)
+        if self.list.table().has_key(key):
+            self.list.delete_name(key)
         item = StringField(value)
         item.name = key
         self.list.append(item)
@@ -460,10 +463,8 @@
         return [(item.name, item) for item in self.list]

     def __delitem__(self, key):
-        table = self.list.table()
-        values = table[key]
-        for value in values:
-            self.list.remove(value)
+        if self.list.table().has_key(key):
+            self.list.delete_name(key)

     def clear(self):
         self.list = FieldList()



-- 
Anders Blomdell                  Email: anders.blomdell@control.lth.se
Department of Automatic Control
Lund University                  Phone:    +46 46 222 4625
P.O. Box 118                     Fax:      +46 46 138118
SE-221 00 Lund, Sweden

Mime
View raw message