On Aug 4, 2009, at 2:16 PM, mdipierro wrote: > > I believe this problem was fixed in 1.65.10. Am I wrong?
I don't have a test case; I've just been reading the source. But I suspect that it's not fixed. Consider the flow when f is a FieldStorage object with list = None: > elif field.type == 'upload': > f = self.vars[fieldname] > fd = fieldname + '__delete' > if f == '': > if self.vars.get(fd, False) or not self.record: > fields[fieldname] = '' > else: > fields[fieldname] = self.record[fieldname] > continue > elif not f: > continue # not sure this ever happens but safety > check > elif not isinstance(f, (str, unicode)): > (source_file, original_filename) = (f.file, > f.filename) We'll still execute the "not f" test, right? And it'll still throw the exception, at least in Python 2.5. And in 2.6, you won't get to the next elif. Is that bad? I'm still confused about what the code is actually trying to accomplish, so I don't know. What *should* be happening in the case that Jose and Fran are having problems with? > > Massimo > > On Aug 4, 3:23 pm, Jonathan Lundell <jlund...@pobox.com> wrote: >> On Aug 4, 2009, at 9:38 AM, Jonathan Lundell wrote: >> >> >> >> >> >>> On Aug 3, 2009, at 8:33 AM, Jose wrote: >> >>>> I have just tried this in Windows XP(r1153) + python 2.5.x >> >>>> db.define_table('unatabla', >>>> Field('nombre'), >>>> Field('imagen', 'upload'), >>>> ) >> >>>> The following mistake takes is produced when I do submit: >> >>>> Error traceback >>>> Traceback (most recent call last): >>>> File "E:\web2py2\gluon\restricted.py", line 178, in restricted >>>> exec ccode in environment >>>> File "E:/web2py2/applications/prueba/controllers/appadmin.py", line >>>> 255, in <module> >>>> File "E:\web2py2\gluon\globals.py", line 101, in <lambda> >>>> self._caller = lambda f: f() >>>> File "E:/web2py2/applications/prueba/controllers/appadmin.py", line >>>> 104, in insert >>>> if form.accepts(request.vars, session): >>>> File "E:\web2py2\gluon\sqlhtml.py", line 809, in accepts >>>> if not f: >>>> File "E:\Python25\lib\cgi.py", line 633, in __len__ >>>> return len(self.keys()) >>>> File "E:\Python25\lib\cgi.py", line 609, in keys >>>> raise TypeError, "not indexable" >>>> TypeError: not indexable >> >>> I took a quick look at the code behind this trace, and I can offer a >>> small clue. I don't know enough about what's going on to offer a >>> solution, but perhaps it'll ring a bell for someone who understands >>> the code better than I do. >> >>> Here's the code in the tree: >> >>>> elif field.type == 'upload': >>>> f = self.vars[fieldname] >>>> fd = fieldname + '__delete' >>>> if not f: >> >>> This used to be f == ''. >> >>>> if self.vars.get(fd, False) or not self.record: >>>> fields[fieldname] = '' >>>> else: >>>> fields[fieldname] = self.record[fieldname] >>>> continue >>>> elif not isinstance(f, (str, unicode)): >>>> (source_file, original_filename) = (f.file, >>>> f.filename) >>>> else: >>>> ### do not know why this happens, it should not >> >>> This comment bothers me, and I wonder if it might be related. >> >>>> (source_file, original_filename) = \ >>>> (cStringIO.StringIO(f), 'file.txt') >>>> logging.warn('here') >>>> fields[fieldname] = field.store(source_file, >>>> original_filename) >>>> logging.warn('there') >>>> if field.uploadfield and not >>>> field.uploadfield==True: >>>> fields[field.uploadfield] = source_file.read() >>>> continue >> >>> In the failing case, f appears to be an instance of FieldStorage, >>> from >>> cgi.py. It appears that Python implements "if not f" as "if not >>> len(f)". FieldStorage defines __len__ as "len(self.keys()), and >>> that's >>> where we run into trouble. >> >>> def keys(self): >>> """Dictionary style keys() method.""" >>> if self.list is None: >>> raise TypeError, "not indexable" >>> keys = [] >>> for item in self.list: >>> if item.name not in keys: keys.append(item.name) >>> return keys >> >>> And self.list is None unless one of two things happens: >> >>> if ctype == 'application/x-www-form-urlencoded': >>> self.read_urlencoded() >>> elif ctype[:10] == 'multipart/': >>> self.read_multi(environ, keep_blank_values, >>> strict_parsing) >>> else: >>> self.read_single() >> >>> Only the first two calls (read_urlencoded() and read_multi()) set >>> self.list to a list. Otherwise it's None, and our 'if not f' will be >>> sent an exception. >> >>> If this case is expected, or at should be a detectable error >>> condition, then perhaps we should catch the exception and treat it >>> as >>> a case of 'not f'. Or something. But as I say, I don't really know >>> enough about the intent of this code to go any farther. >> >> I see that in 2.6, FieldStorage has a __nonzero__() method that does >> the right thing (and will be used in preference to __len__). >> >> So part of the problem you guys are seeing might be the difference in >> how 2.6 (vs 2.5) handles "if not f". >> >> Anyway, I don't see how the sqlhtml upload logic deals with f being a >> FieldStorage object. > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "web2py-users" group. To post to this group, send email to web2py@googlegroups.com To unsubscribe from this group, send email to web2py+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/web2py?hl=en -~----------~----~----~----~------~----~------~--~---