Edgewall Software

Opened 13 years ago

Last modified 12 years ago

#523 new defect

exception when externally including py:match templates that match elem0[@attribute]/elem1

Reported by: Lutz Wolf <genshi@…> Owned by: cmlenz
Priority: major Milestone:
Component: Template processing Version: devel
Keywords: Cc:

Description

The following Python script and its output illustrate a problem that I ran into with the latest SVN trunk of Genshi. Processing breaks with a stack trace if I include an external template with a py:match element within a <html xmlns:py...> root element, _and_ use an Xpath expression like "ul[@id]/li/item" that matches the id attribute of the ul element. I get no stack trace if I use the py:match element as the root element of the included template, or if I include the py:match element directly (I'd rather use a separate file), or if I use the XPath expression "ul/li/item" (I need to match the id, however).


Script:

from genshi.template import MarkupTemplate
 
template1="""<?xml version='1.0' encoding='utf-8'?>
<html xmlns:py="http://genshi.edgewall.org/"
      xmlns:xi="http://www.w3.org/2001/XInclude">
 
    <head>
        <title>Genshi Test Page</title>
    </head>
    <body>
 
        <!--! match the content element -->
        <div py:match="content" py:strip="True">
            <div class="content">
                <ul id="ul_id">
                    <li py:for="test in xrange(5)">
                        <item>${test}</item>
                    </li>
                </ul>
            </div>
        </div>
 
        <py:match path="ul[@id='ul_id']/li/item"><div>test test</div></py:match>
 
        <content/>
 
    </body>
 
</html>
"""
 
print '=== About to render template 1, with inline py:match ==========='
tmpl = MarkupTemplate(template1)
stream = tmpl.generate()
print(stream.render('xhtml'))
print '================================================================'
print '=== About to render template 2, including the match template ==='
print '--- template to include ----------------------------------------'
print open('genshi-include-test.html').read().strip()
print '----------------------------------------------------------------'
print '--- genshi output ----------------------------------------------'
template2 = template1.replace("""<py:match path="ul[@id='ul_id']/li/item"><div>test test</div></py:match>""",
                              """<xi:include href="genshi-include-test.html" />""")
 
tmpl = MarkupTemplate(template2)
stream = tmpl.generate()
print(stream.render('xhtml'))
print '----------------------------------------------------------------'


Skript output

================================================================
=== About to render template 1, with inline py:match ===========
<html>
    <head>
        <title>Genshi Test Page</title>
    </head>
    <body>
            <div class="content">
                <ul id="ul_id">
                    <li>
                        <div>test test</div>
                    </li><li>
                        <div>test test</div>
                    </li><li>
                        <div>test test</div>
                    </li><li>
                        <div>test test</div>
                    </li><li>
                        <div>test test</div>
                    </li>
                </ul>
            </div>
    </body>
</html>
================================================================
=== About to render template 2, including the match template ===
--- template to include ----------------------------------------
<html xmlns:py="http://genshi.edgewall.org/"
      xmlns:xi="http://www.w3.org/2001/XInclude">
 
      <py:match path="ul[id='ul_id']/li/item">
        <div>test test</div>
    </py:match>
</html>
----------------------------------------------------------------
--- genshi output ----------------------------------------------
Traceback (most recent call last):
  File "genshi-test.py", line 47, in <module>
    print(stream.render('xhtml'))
  File "genshi/build/lib.linux-x86_64-2.7/genshi/core.py", line 184, in render
    return encode(generator, method=method, encoding=encoding, out=out)
  File "genshi/build/lib.linux-x86_64-2.7/genshi/output.py", line 57, in encode
    return _encode(''.join(list(iterator)))
  File "genshi/build/lib.linux-x86_64-2.7/genshi/output.py", line 350, in __call__
    for kind, data, pos in stream:
  File "genshi/build/lib.linux-x86_64-2.7/genshi/output.py", line 669, in __call__
    for kind, data, pos in stream:
  File "genshi/build/lib.linux-x86_64-2.7/genshi/output.py", line 774, in __call__
    for kind, data, pos in chain(stream, [(None, None, None)]):
  File "genshi/build/lib.linux-x86_64-2.7/genshi/output.py", line 594, in __call__
    for ev in stream:
  File "genshi/build/lib.linux-x86_64-2.7/genshi/core.py", line 289, in _ensure
    for event in stream:
  File "genshi/build/lib.linux-x86_64-2.7/genshi/template/base.py", line 618, in _include
    for event in stream:
  File "genshi/build/lib.linux-x86_64-2.7/genshi/template/markup.py", line 348, in _match
    test(event, namespaces, ctxt, updateonly=True)
  File "genshi/build/lib.linux-x86_64-2.7/genshi/path.py", line 129, in _test
    pos_queue = deque([(pos, cou, []) for pos, cou in stack[-1]])
IndexError: list index out of range

Change History (1)

comment:1 Changed 12 years ago by anonymous

I believe I have a similar issue. The use case matches and I have the same exception and stack trace. Let me know if this is worked on and whether I could provide some useful information.

Note: See TracTickets for help on using tickets.