Edgewall Software

Opened 18 years ago

Closed 18 years ago

Last modified 18 years ago

#35 closed defect (fixed)

py:match and py:def weirdness

Reported by: cboos Owned by: cmlenz
Priority: major Milestone: 0.3
Component: Template processing Version: 0.2
Keywords: Cc:

Description

When a py:def is present in a element which is being matched, calls to that macro from outside a py: directive will fail, as the function is not yet registered.

The problem is a bit hard to describe, so I'll give an example:

  • markup/tests/template.py

     
    530530    #      </span>
    531531    #    </div>""", str(tmpl.generate()))
    532532
     533    def test_def_in_matched(self):
     534        tmpl = Template("""<doc xmlns:py="http://markup.edgewall.org/">
     535          <head py:match="head">${select('*')}</head>
     536          <head>
     537            <py:def function="maketitle(test)"><b py:replace="test" /></py:def>
     538            <title>${maketitle(True)}</title>
     539          </head>
     540        </doc>""")
     541        self.assertEqual("""<doc>
     542          <head><title>True</title></head>
     543        </doc>""", str(tmpl.generate()))
    533544
    534545class StripDirectiveTestCase(unittest.TestCase):
    535546    """Tests for the `py:strip` template directive."""

Gives:

...
ERROR: test_def_in_matched (markup.tests.template.MatchDirectiveTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Workspace\src\trac\Markup\trunk\markup\tests\template.py", line 541, in test_def_in_matched
    self.assertEqual("""<doc>
  File "C:\Workspace\src\trac\Markup\trunk\markup\core.py", line 131, in __str__
    return self.render()
  File "C:\Workspace\src\trac\Markup\trunk\markup\core.py", line 93, in render
    output = u''.join(list(generator))
  File "C:\Workspace\src\trac\Markup\trunk\markup\output.py", line 111, in __call__
    kind, data, pos = stream.next()
  File "C:\Workspace\src\trac\Markup\trunk\markup\output.py", line 497, in next
    return self.iterable.next()
  File "C:\Workspace\src\trac\Markup\trunk\markup\output.py", line 442, in __call__
    for kind, data, pos in chain(stream, [(None, None, None)]):
  File "C:\Workspace\src\trac\Markup\trunk\markup\core.py", line 150, in _ensure
    for event in stream:
  File "C:\Workspace\src\trac\Markup\trunk\markup\template.py", line 952, in _flatten
    for kind, data, pos in stream:
  File "C:\Workspace\src\trac\Markup\trunk\markup\template.py", line 989, in _match
    kind, data, pos = stream.next()
  File "C:\Workspace\src\trac\Markup\trunk\markup\template.py", line 924, in _eval
    result = data.evaluate(ctxt)
  File "c:\workspace\src\trac\markup\trunk\markup\eval.py", line 91, in evaluate
    retval = eval(self.code, {'data': data,
  File "<string>", line 5, in <Expression u"maketitle(True)">
TypeError: 'NoneType' object is not callable

----------------------------------------------------------------------
Ran 232 tests in 0.531s

FAILED (errors=1)

Note that if the call is done from within a py: directive (e.g. <py:def test="True">${maketitle(content)}</py:def>), then the test succeeds.

P.S: tested with latest r239; you should add the 0.2 and maybe devel versions.

Change History (4)

comment:1 Changed 18 years ago by cboos

  • Priority changed from critical to major

Also, I just figured out that if the <py:def> is defined before the element being matched (e.g. before the <head> in the example above), the test will also succeed.

So I'm lowering the prio, as there are several workarounds to this problem.

comment:2 Changed 18 years ago by anonymous

  • Milestone set to 0.3
  • Version set to 0.2

comment:3 Changed 18 years ago by cmlenz

  • Status changed from new to assigned

comment:4 Changed 18 years ago by cmlenz

  • Resolution set to fixed
  • Status changed from assigned to closed

Should be fixed in [258]. I've integrated the example above as a unit test. Thanks for the detailed report!

Note: See TracTickets for help on using tickets.