diff --git a/CHANGES.rst b/CHANGES.rst index d277467..ca39579 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -14,7 +14,10 @@ - Add the ``string`` and ``nocall`` functions for use inside Python expressions. See `issue 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 + `_. 3.0 (2016-09-02) ================ diff --git a/src/z3c/pt/pagetemplate.py b/src/z3c/pt/pagetemplate.py index 39ca761..8c827fe 100644 --- a/src/z3c/pt/pagetemplate.py +++ b/src/z3c/pt/pagetemplate.py @@ -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) diff --git a/src/z3c/pt/tests/test_templates.py b/src/z3c/pt/tests/test_templates.py index e241f8a..49c138b 100644 --- a/src/z3c/pt/tests/test_templates.py +++ b/src/z3c/pt/tests/test_templates.py @@ -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 @@ -248,3 +248,11 @@ class Template(object): bound = pagetemplate.BoundPageTemplate(Template(), 'render') self.assertEqual("", 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__)