marrow / cinje

A Pythonic and ultra fast template engine DSL.
MIT License
33 stars 0 forks source link

Iteration prior to buffer construction constructs buffer too late. #21

Closed amcgregor closed 8 years ago

amcgregor commented 8 years ago

Simplest test case:

# encoding: cinje

: def testcase
    : for i in ('hello', 'world')
        ${i}

Ignoring default imports, optimizations, and line mapping, the transformed result is currently:

def testcase():
    for i in ('hello', 'world'):
        _buffer = []
        __w, __ws = _buffer.extend, _buffer.append

        __w((
            '\t\t',
            _escape(i),
            '\n'
        ))

    yield "".join(_buffer)

Note the dangerous location of buffer construction. If the loop were empty, it would not be called, but the code transformer considers the buffer prepared after that point regardless. In the empty test case, the subsequent yield will explode as _buffer would be undefined. Additionally, the buffer is overwritten on each iteration here.

Temporary workaround: include some emitted content prior to a function's first iterator. An HTML comment works well.

Simple fix: force buffer construction after function declaration.

amcgregor commented 8 years ago

Corrected in 0ff337d.