Path expression traversal in z3c.pt

Albertas Agejevas <[email protected]>
Newsgroups gmane.comp.web.zope.devel
Message-ID <[email protected]>
Hi,

I tried switching to z3c.pt in one of our projects and found an
incompatibility with zope.app.pagetemplate.  It is not obvious whether
it is a bug or a feature, so I thought I should bring it up here.
Here is a doctest illustrating the incompatibility.

First, let's set up both types of templates:

    >>> from zope.pagetemplate.pagetemplate import PageTemplate
    >>> from zope.app.pagetemplate.engine import TrustedAppPT
    >>> class ZopePageTemplate(TrustedAppPT, PageTemplate):
    ...      def __init__(self, source):
    ...           self.pt_edit(source, '')

    >>> from z3c.pt.pagetemplate import PageTemplate as Z3CPageTemplate
    >>> from z3c.pt.expressions import path_translator
    >>> from zope.component import provideUtility
    >>> provideUtility(path_translator, name="path")

Normally, traversing in path expressions prefers attributes over
items, but makes an exception for dict objects.

    >>> arg = {'copy': 1}
    >>> ZopePageTemplate("<p tal:content='options/arg/copy'/>")(arg=arg)
    u'<p>1</p>\n'

    >>> Z3CPageTemplate("<p tal:content='options/arg/copy'/>")(arg=arg)
    u'<p>1</p>'

However, attribute lookup takes precedence for other dict-like objects:

    >>> from UserDict import UserDict
    >>> arg = UserDict()
    >>> arg['copy'] = '1'

    >>> ZopePageTemplate("<p tal:content='options/arg/copy'/>")(arg=arg)
    u"<p>{'copy': '1'}</p>\n"

    >>> Z3CPageTemplate("<p tal:content='options/arg/copy'/>")(arg=arg)
    u"<p>{'copy': '1'}</p>"

However, Zope lets the user override this behaviour by providing a
traversing adapter:

    >>> from zope.traversing.interfaces import ITraversable
    >>> from zope.interface import implements
    >>> class MyDict(UserDict):
    ...     implements(ITraversable)
    ...     def traverse(self, name, path):
    ...          return self[name]

    >>> arg = MyDict()
    >>> arg['copy'] = '1'
    >>> ZopePageTemplate("<p tal:content='options/arg/copy'/>")(arg=arg)
    u'<p>1</p>\n'

    >>> Z3CPageTemplate("<p tal:content='options/arg/copy'/>")(arg=arg)
    u"<p>{'copy': '1'}</p>"

Here the behaviour diverges, as
zope.app.pagetemplates.engine.ZopeTraverser looks for an ITraversable
adapter and gets DefaultTraversable to implement the default
behaviour, whereas z3c.pt.expressions.ZopeTraverser tries the
attribute lookup before looking up the adapter.

To summarize, z3c.pt prefers attribute lookup to traversable adapters,
whereas zope.app.pagetemplate doesn't.

Is this divergence a bug or a feature?  Anyhow, it should be either
unified or documented.

Albertas
-- 
http://pov.lt -- ZTK/BlueBream consulting and development
_______________________________________________
Zope-Dev maillist  -  [email protected]
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.