Cannot run under Python 3.5.2 - "TypeError: 'generator' object is not subscriptable"
Closed this issue · 6 comments
When running the server under Python 2.7.12, everything seems to work. When running it under 3.5.2 and trying to push documentation using the exact same commands, the server returns HTTP 500 (internal server error), and it prints this on console:
File "C:\Users\davidfallah\AppData\Local\Programs\Python\Python35-32\lib\site-packages\flask\app.py", line 1988, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\davidfallah\AppData\Local\Programs\Python\Python35-32\lib\site-packages\flask\app.py", line 1641, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\davidfallah\AppData\Local\Programs\Python\Python35-32\lib\site-packages\flask\app.py", line 1544, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\davidfallah\AppData\Local\Programs\Python\Python35-32\lib\site-packages\flask\_compat.py", line 33, in reraise
raise value
File "C:\Users\davidfallah\AppData\Local\Programs\Python\Python35-32\lib\site-packages\flask\app.py", line 1639, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\davidfallah\AppData\Local\Programs\Python\Python35-32\lib\site-packages\flask\app.py", line 1625, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\Users\davidfallah\Documents\hostthedocs\hostthedocs\__init__.py", line 22, in hmfd
request.files.values()[0].stream,
TypeError: 'generator' object is not subscriptable
I changed request.files.values()[0].stream
to list(request.files.values())[0].stream
and this seems to make it work under both Python 2.7.12 and 3.5.2. I have not tested for other versions.
Hmmm, interesting, I have it running under other 3.x versions in Tox/Travis with no problems. Happy to accept that change as a Pull Request, just open it and I'll merge it. Also please add whatever Python 3.5 to the travis/tox configs for extra points!
Which version of pypy do you test against?
Whatever Travis has as pypy, so I assume the 2.x-compatible line? Check out the .travis.yml
and tox.ini
. PyPy3 was still pretty young when I set things up.
Have you actually tried running your server on any version of Python 3? Because I've got the same error when I try running on Python 3.3. I think the issue is just that the tests you've currently got don't expose this bug, so I'll need to add it.
I've also been digging and I think I've found the root cause of the problem. I haven't worked with flask/werkzeug/etc. and I only have a rudimentary understanding of what they are, but the 'request' object you use in request.files.values()[0].stream
(where the exception is thrown) is an instance of werkzeug.wrappers.BaseRequest
(or close enough). That class exposes a property files
which is an instance of werkzeug.datastructures.ImmutableMultiDict
. This essentially implements the dict
interface, but it's decorated by a function that changes the way it returns an iterator depending on whether you're using a Python 2 or Python 3 interpreter:
def native_itermethods(names):
if not PY2:
return lambda x: x
def setviewmethod(cls, name):
viewmethod_name = 'view%s' % name
viewmethod = lambda self, *a, **kw: ViewItems(self, name, 'view_%s' % name, *a, **kw)
viewmethod.__doc__ = \
'"""`%s()` object providing a view on %s"""' % (viewmethod_name, name)
setattr(cls, viewmethod_name, viewmethod)
def setitermethod(cls, name):
itermethod = getattr(cls, name)
setattr(cls, 'iter%s' % name, itermethod)
listmethod = lambda self, *a, **kw: list(itermethod(self, *a, **kw))
listmethod.__doc__ = \
'Like :py:meth:`iter%s`, but returns a list.' % name
setattr(cls, name, listmethod)
def wrap(cls):
for name in names:
setitermethod(cls, name)
setviewmethod(cls, name)
return cls
return wrap
Given the following code:
>>> from werkzeug.datastructures import ImmutableMultiDict
>>> a = ImmutableMultiDict({'a':1,'b':2})
>>> a.values()
Under Python 2, this yields [1, 2]
.
Under Python 3, this yields <generator object values at 0x104a63dc0>
.
The former is subscriptable whereas the latter isn't, which explains the error I get.
Ahaha, very nice find, and excellent report!
You can guess from the commit history I haven't used this in a while; I could fix this this weekend probably, unless you want to submit a PR (for which I would be much appreciative!)?
I'll try.