[ 
https://issues.apache.org/jira/browse/FREEMARKER-68?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16123117#comment-16123117
 ] 

Daniel Dekany edited comment on FREEMARKER-68 at 8/11/17 10:00 AM:
-------------------------------------------------------------------

The problem is not specific to {{\?\?}} actually. That way it works is that 
{{freemarker.ext.jython.JythonModel.get(String)}} is called (which is just an 
implementation of {{TemplateHashModel.get(String)}} as far as FreeMarker is 
concerned), and then if that returns {{null}} then {{??}} or the other 
existence handlers operators (most notably {{exp!defaultExp}}) handle it. That 
particular {{get}} implementation calls {{PyObject.__findattr__(key)}}, and if 
that returns {{null}} then it also tries {{PyObject.__finditem__(key)}}. If 
both was {{null}}, then {{get}} returns {{null}}, and {{??}} works. I'm not 
sure what the proper {{PyObject}} calls would be... And frankly, I think that 
the Jython wrapper is some early implementation hastily dropped in back then by 
the earlier developers, maybe to catch some attention from then much more 
active Jython community, but then it was practically abandoned. But as its part 
of {{freemarker.jar}}, it stuck there for backward compatibility. So I can 
imagine there's a lot to improve there. If anyone cares to improve it (or even 
create an external wrapper that's better, as then there are no backward 
compatibility constraints), it's highly welcome. Similarly here, it's not 
likely that anything will happen without a Pull Request or patch, which also 
considers backward compatibility (means, certainly we will need to add 
{{incompatibleImprovements}} setting to the {{JythonWrapper}}, similarly as 
{{DefaultObjectWrapper}} has it too).


was (Author: ddekany):
The problem is not specific to {{??}} actually. That way it works is that 
{{freemarker.ext.jython.JythonModel.get(String)}} is called (which is just an 
implementation of {{TemplateHashModel.get(String)}} as far as FreeMarker is 
concerned), and then if that returns {{null}} then {{??}} or the other 
existence handlers operators (most notably {{exp!defaultExp}}) handle it. That 
particular {{get}} implementation calls {{PyObject.__findattr__(key)}}, and if 
that returns {{null}} then it also tries {{PyObject.__finditem__(key)}}. If 
both was {{null}}, then {{get}} returns {{null}}, and {{??}} works. I'm not 
sure what the proper {{PyObject}} calls would be... And frankly, I think that 
the Jython wrapper is some early implementation hastily dropped in back then by 
the earlier developers, maybe to catch some attention from then much more 
active Jython community, but then it was practically abandoned. But as its part 
of {{freemarker.jar}}, it stuck there for backward compatibility. So I can 
imagine there's a lot to improve there. If anyone cares to improve it (or even 
create an external wrapper that's better, as then there are no backward 
compatibility constraints), it's highly welcome. Similarly here, it's not 
likely that anything will happen without a Pull Request or patch, which also 
considers backward compatibility (means, certainly we will need to add 
{{incompatibleImprovements}} setting to the {{JythonWrapper}}, similarly as 
{{DefaultObjectWrapper}} has it too).

> Double-question mark operator does not properly test for attributes
> -------------------------------------------------------------------
>
>                 Key: FREEMARKER-68
>                 URL: https://issues.apache.org/jira/browse/FREEMARKER-68
>             Project: Apache Freemarker
>          Issue Type: Bug
>          Components: engine
>    Affects Versions: 2.3.23
>            Reporter: Jason Sachs
>
> The double-question mark operator doesn't work properly with some Jython 
> objects.
> It works properly with dicts.
> It does not work properly with custom classes and triggers an item lookup.
> Example setup: (I can't post a complete self-contained example, sorry)
> Jython code called before FreeMarker template is rendered:
> {code}
> class VoodooDoll(object):
>     def pinch(self):
>         return "ouch"
> model['test1'] = dict(voodooDoll=VoodooDoll())
> {code}
> FreeMarker template:
> {code}
> <#if test1.blah??>
> blah present
> </#if>
> <#if test1.voodooDoll??>
> voodoo doll present
> </#if>
> <#if test1.voodooDoll.pinch??>
> voodoo doll pinch present
> </#if>
> <#if test1.voodooDoll.hit??>
> voodoo doll hit present
> </#if>
> {code}
> This produces the output
> {noformat}
> voodoo doll present
> voodoo doll pinch present
> {noformat}
> so the first three {{#if}} tests work properly, but the fourth one causes 
> this error:
> {noformat}
>       - Failed at: #if test1.voodooDoll.hit??  [in template 
> "source\\aux-files\\parameters.html.template" at line 58, column 1]
> ...
> Caused by: TypeError: 'VoodooDoll' object is unsubscriptable
>       at org.python.core.Py.TypeError(Py.java:235)
>       at org.python.core.PyObject.__finditem__(PyObject.java:585)
>       at 
> org.python.core.PyObjectDerived.__finditem__(PyObjectDerived.java:861)
> {noformat}



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to