Skip to content

Commit

Permalink
Add __self__ and __func__ for bound templates. Fixes #9
Browse files Browse the repository at this point in the history
  • Loading branch information
jamadden committed Oct 17, 2017
1 parent fd8c060 commit 35f9524
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 11 deletions.
5 changes: 4 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
- Add the ``string`` and ``nocall`` functions for use inside Python
expressions. See `issue 2
<https://github.com/zopefoundation/z3c.pt/issues/2>`_.

- Make bound page templates have ``__self__`` and ``__func__``
attributes to be more like Python 3 bound methods. (``im_func`` and
``im_self`` remain available.) See `issue 9
<https://github.com/zopefoundation/z3c.pt/issues/9>`_.

3.0 (2016-09-02)
================
Expand Down
20 changes: 11 additions & 9 deletions src/z3c/pt/pagetemplate.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,24 +278,26 @@ class BoundPageTemplate(object):
the class instance on access, which is implemented using this
helper class."""

im_self = None
im_func = None
__self__ = None
__func__ = None

def __init__(self, pt, render):
object.__setattr__(self, 'im_self', pt)
object.__setattr__(self, 'im_func', render)
object.__setattr__(self, '__self__', pt)
object.__setattr__(self, '__func__', render)

macros = property(lambda self: self.im_self.macros)
filename = property(lambda self: self.im_self.filename)
im_self = property(lambda self: self.__self__)
im_func = property(lambda self: self.__func__)
macros = property(lambda self: self.__self__.macros)
filename = property(lambda self: self.__self__.filename)

def __call__(self, *args, **kw):
kw.setdefault('args', args)
return self.im_func(**kw)
return self.__func__(**kw)

def __setattr__(self, name, v):
raise AttributeError("Can't set attribute", name)

def __repr__(self):
return "<%s.Bound%s %r>" % (
type(self.im_self).__module__,
type(self.im_self).__name__, self.filename)
type(self.__self__).__module__,
type(self.__self__).__name__, self.filename)
10 changes: 9 additions & 1 deletion src/z3c/pt/tests/test_templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ def test_setattr(self):
bound = pagetemplate.BoundPageTemplate(None, None)
with self.assertRaisesRegexp(AttributeError,
"Can't set attribute"):
setattr(bound, 'im_self', 42)
setattr(bound, '__self__', 42)

def test_repr(self):
# It requires the 'filename' attribute
Expand All @@ -248,3 +248,11 @@ class Template(object):
bound = pagetemplate.BoundPageTemplate(Template(), 'render')
self.assertEqual("<z3c.pt.tests.test_templates.BoundTemplate 'file.pt'>",
repr(bound))

def test_attributes(self):
func = object()
bound = pagetemplate.BoundPageTemplate(self, func)
self.assertIs(self, bound.im_self)
self.assertIs(self, bound.__self__)
self.assertIs(func, bound.im_func)
self.assertIs(func, bound.__func__)

0 comments on commit 35f9524

Please sign in to comment.