pystache icon indicating copy to clipboard operation
pystache copied to clipboard

Rendering complex types

Open dagostinelli opened this issue 11 years ago • 6 comments

Pystache might be having problems rendering data from a complex type. It seems to be fine with dictionaries, however. That said, it doesn't seem to traverse dictionaries that contain complex objects.

Please refer to this: http://stackoverflow.com/questions/25827884/mustache-pystache-rendering-complex-objects

This breaks:

import pystache

template = u'''
  {{greeting}}
   Property 1 is {{information.property1}}
   Property 2 is {{information.property2}}
'''

class Struct:
  pass

root = Struct()
child = Struct()
setattr(child, "property1", "Bob")
setattr(child, "property2", 42)
setattr(root, "information", child)
setattr(root, "greeting", "Hello")

context = root

print pystache.render(template, context)

It yields:

  Property 1 is
  Property 2 is

Expected output is:

Hello
  Property 1 is bob
  Property 2 is 42

If you change the last two lines to this:

context = root.__dict__
print pystache.render(template, context)

It will traverse the first dictionary, but then not traverse the inner objects, so you get this:

  Hello
   Property 1 is 
   Property 2 is 

The following works, but it's a full dictionary

import pystache
template = u'''
  {{greeting}}
   Property 1 is {{information.property1}}
   Property 2 is {{information.property2}}
'''

context={
    'greeting':'Hello',
    'information':{
         'property1':'bob',
         'property2':42
    }
}
print pystache.render(template,context)

yeilds:

Hello
  Property 1 is bob
  Property 2 is 42

dagostinelli avatar Sep 15 '14 00:09 dagostinelli

The problem is in context.py line 55, I think.

elif type(context).__module__ != _BUILTIN_MODULE:

According to the comment there , "Instances of user-defined classes on the other hand, for example, # are considered objects by the test above."

But this is clearly false:

class C():
    pass

c=C()

print type(c).__module__ 

yields builtin

However, sabercups example does work if we replace

class Struct:

with

class Struct(object):

trvrm avatar Sep 15 '14 13:09 trvrm

Just to clarify, if you change this line--

class C():

to--

class C(object):

Does it still not behave as desired? The issue here is old vs new-style classes. IIRC, I believe the code was written with new-style classes in mind.

cjerdonek avatar Sep 15 '14 16:09 cjerdonek

Yes, it works fine if we use

class C(object):

So this issue should be labelled "pystache doesn't traverse old-style classes". Which may be acceptable - I don't fully understand the difference between new and old style classes.

trvrm avatar Sep 15 '14 16:09 trvrm

Here's an SO post on the subject (one of many I'm sure):

http://stackoverflow.com/questions/54867/old-style-and-new-style-classes-in-python

Old-style classes were the way classes were prior to Python 2.2. I'm not sure it's worth supporting old-style because it's a legacy style. For example, in Python 3 all classes are new-style.

cjerdonek avatar Sep 15 '14 16:09 cjerdonek

What about backwards compatibility with Python 2? There's still a lot of that around.

In any event, perhaps a comment then in pystache.render() to remind everyone to use classes derived from object.

dagostinelli avatar Sep 15 '14 17:09 dagostinelli

The oldest version that Pystache supports is Python 2.4, and new-style classes were around back then. I think a code comment and/or note in a docstring comment would be fine.

cjerdonek avatar Sep 15 '14 17:09 cjerdonek