Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Confusing error w/ Python 3 and templates that use iteritems() #150

Closed
samatjain opened this Issue · 1 comment

2 participants

@samatjain

Consider:

#!/usr/bin/env python3

from collections import OrderedDict

import jinja2

t = '''
{% for key, value in d.iteritems() %}
* {{ key }}: {{ value }}
{% endfor %}
'''

jt = jinja2.Template(t)

d = OrderedDict()
d['one'] = 1
d['two'] = 2
d['three'] = 3

print(jt.render(d=d))

When run w/ Python 3, you get an confusing exception:

Traceback (most recent call last):
  File "jinja2-OrderedDict.py", line 20, in <module>
    print(jt.render(d=d))
  File "/usr/lib/python3/dist-packages/jinja2/environment.py", line 895, in render
    return self.environment.handle_exception(exc_info, True)
  File "/usr/lib/python3/dist-packages/jinja2/environment.py", line 671, in handle_exception
    raise exc_value.with_traceback(tb)
  File "<template>", line 2, in <module>
jinja2.exceptions.UndefinedError: b"'collections.OrderedDict object' has no attribute 'iteritems'"

This is because the template uses iteritems, which is removed in Python 3. From the above exception, it's not clear the problem is in the template—it should be.

It works for normal Python 3 dictionaries because lines 205–210 of Jinja2 v2.61 add back an iteritems method:

    # not available on python 3
    if hasattr(dict, 'iterkeys'):
        iterkeys = _all('iterkeys')
        itervalues = _all('itervalues')
        iteritems = _all('iteritems')
    del _all

What's the best way to fix this? Better detect dict-like objects, try to spit out a better error, etc?

@mitsuhiko
Owner

Dictionaries do not have iteritem methods in 3.x. You will need to change to .items(). Nothing I can do about that.

@mitsuhiko mitsuhiko closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.