Edgewall Software

Opened 6 years ago

Last modified 2 years ago

#323 new enhancement

Error message is confusing if <py:for ...> lacks each=""

Reported by: brandon@… Owned by: cmlenz
Priority: major Milestone: 0.6.1
Component: Template processing Version: 0.5.1
Keywords: Cc: brandon@…


I probably use too many templating languages, but a few minutes ago I wrote this when using Genshi:

<py:for loop="item in mylist">

and was greeted with the perplexing error message "TypeError?: argument of type 'NoneType?' is not iterable". This was rather bewildering and it took several minutes for me to work out what was going wrong. It seems that the error message is, instead of pointing out the actual error, leaking an internal detail about how Genshi works: when it asks itself what value I supplied for each="", it gets back the answer None if I failed to specify each="".

Could the error message be re-worded to something like: "py:for is missing each="" attribute" or something?

That would point users at the solution much more effectively.


Attachments (0)

Change History (2)

comment:1 Changed 6 years ago by cmlenz

  • Milestone changed from 0.6 to 0.6.1

comment:2 Changed 5 years ago by Carsten Klein <carsten.klein@…>

The error results from the statement

if ' in ' not in value:

Here, the NoneType? is not iterable, see the attached patch that will issue the error on both attach and on init

  • directives.py

    338338    __slots__ = ['assign', 'filename']
    340340    def __init__(self, value, template, namespaces=None, lineno=-1, offset=-1):
    341         if ' in ' not in value:
    342             raise TemplateSyntaxError('"in" keyword missing in "for" directive',
     342        try:
     343            if ' in ' not in value:
     344                raise TemplateSyntaxError('"in" keyword missing in "for" '
     345                                          'directive',
     346                                          template.filepath, lineno, offset)
     347        except:
     348            raise TemplateSyntaxError('"value" must be of type "str" in '
     349                                      '"for" directive',
    343350                                      template.filepath, lineno, offset)
    344352        assign, value = value.split(' in ', 1)
    345353        ast = _parse(assign, 'exec')
    346354        value = 'iter(%s)' % value.strip()
    351359    @classmethod
    352360    def attach(cls, template, stream, value, namespaces, pos):
    353361        if type(value) is dict:
     362            if 'each' not in value:
     363                raise TemplateSyntaxError('"each" attribute missing in "for"'
     364                                          ' directive',
     365                                          template.filepath, *pos[1:])
    354366            value = value.get('each')
    355368        return super(ForDirective, cls).attach(template, stream, value,
    356369                                               namespaces, pos)

Add Comment

Modify Ticket

Change Properties
Set your email in Preferences
as new The owner will remain cmlenz.
as The resolution will be set. Next status will be 'closed'.
to The owner will be changed from cmlenz to the specified user. Next status will be 'new'.
The owner will be changed from cmlenz to anonymous. Next status will be 'assigned'.

E-mail address and user name can be saved in the Preferences.

Note: See TracTickets for help on using tickets.