src/pyams_template/template.py
changeset 15 c3d0112a61f6
parent 11 be5b3d594a84
child 16 ac179d1bfc0b
--- a/src/pyams_template/template.py	Mon Nov 25 15:46:23 2019 +0100
+++ b/src/pyams_template/template.py	Tue Nov 26 10:01:36 2019 +0100
@@ -10,42 +10,47 @@
 # FOR A PARTICULAR PURPOSE.
 #
 
-__docformat__ = 'restructuredtext'
+"""PyAMS_template.template module
 
+This module provides Pyramid decorators which can be used to register a Chameleon template for
+a given view
+"""
 
-# import standard library
 import inspect
 import os
+
 import venusian
-
-# import interfaces
-from pyams_template.interfaces import IPageTemplate, IContentTemplate, ILayoutTemplate
+from pyramid.exceptions import ConfigurationError
 from pyramid.interfaces import IRequest
 from pyramid_chameleon.interfaces import IChameleonTranslate
-
-# import packages
-from pyramid.exceptions import ConfigurationError
 from pyramid_chameleon.zpt import PyramidPageTemplateFile
 from zope.component import queryUtility
 from zope.component.globalregistry import getGlobalSiteManager
 from zope.interface import directlyProvides
 
+from pyams_template.interfaces import IContentTemplate, ILayoutTemplate, IPageTemplate
 
-configuration_settings = {}
+
+__docformat__ = 'restructuredtext'
 
 
-class TemplateFactory(object):
-    """Template factory."""
+CONFIGURATION_SETTINGS = {}
+
+
+class TemplateFactory:
+    """Base template factory"""
 
     template = None
 
-    def __init__(self, filename, contentType, macro=None):
-        self.contentType = contentType
+    def __init__(self, filename, content_type, macro=None):
+        self.content_type = content_type
         self.template = PyramidPageTemplateFile(filename,
-                                                content_type=contentType,
+                                                content_type=content_type,
                                                 macro=macro,
-                                                auto_reload=configuration_settings.get('reload_templates', False),
-                                                debug=configuration_settings.get('debug_templates', False),
+                                                auto_reload=CONFIGURATION_SETTINGS.get(
+                                                    'reload_templates', False),
+                                                debug=CONFIGURATION_SETTINGS.get(
+                                                    'debug_templates', False),
                                                 translate=queryUtility(IChameleonTranslate))
         self.macro = self.template.macro = macro
 
@@ -53,27 +58,44 @@
         return self.template
 
 
-class BoundViewTemplate(object):
-    def __init__(self, pt, ob):
-        object.__setattr__(self, 'im_func', pt)
-        object.__setattr__(self, 'im_self', ob)
+class BoundViewTemplate:
+    """Bound view template"""
+
+    __self__ = None
+    __func__ = None
+
+    def __init__(self, tmpl, obj):
+        object.__setattr__(self, '__func__', tmpl)
+        object.__setattr__(self, '__self__', obj)
 
-    def __call__(self, *args, **kw):
-        if self.im_self is None:
+    @property
+    def im_self(self):
+        """im_self property"""
+        return self.__self__
+
+    @property
+    def im_func(self):
+        """im_func property"""
+        return self.__func__
+
+    def __call__(self, *args, **kwargs):
+        if self.__self__ is None:
             im_self, args = args[0], args[1:]
         else:
-            im_self = self.im_self
-        return self.im_func(im_self, *args, **kw)
+            im_self = self.__self__
+        return self.__func__(im_self, *args, **kwargs)  # pylint: disable=not-callable
 
     def __setattr__(self, name, v):
         raise AttributeError("Can't set attribute", name)
 
     def __repr__(self):
-        return "<BoundViewTemplate of %r>" % self.im_self
+        return "<BoundViewTemplate of %r>" % self.__self__
 
 
-class ViewTemplate(object):
-    def __init__(self, provides=IPageTemplate, name=u''):
+class ViewTemplate:
+    """View template class"""
+
+    def __init__(self, provides=IPageTemplate, name=''):
         self.provides = provides
         self.name = name
 
@@ -85,37 +107,46 @@
             template = registry.getMultiAdapter((instance, instance.request),
                                                 self.provides, name=self.name)
 
-        keywords.update({'context': instance.context,
-                         'request': instance.request,
-                         'view': instance,
-                         'translate': queryUtility(IChameleonTranslate)})
+        keywords.update({
+            'context': instance.context,
+            'request': instance.request,
+            'view': instance,
+            'translate': queryUtility(IChameleonTranslate)
+        })
         return template(*args, **keywords)
 
-    def __get__(self, instance, type):
+    def __get__(self, instance, type):  # pylint: disable=redefined-builtin
         return BoundViewTemplate(self, instance)
 
-get_view_template = ViewTemplate
+
+get_view_template = ViewTemplate  # pylint: disable=invalid-name
 
 
 class GetPageTemplate(ViewTemplate):
+    """Page template getter class"""
 
     def __init__(self, name=u''):
+        # pylint: disable=super-init-not-called
         self.provides = IContentTemplate
         self.name = name
 
-get_page_template = GetPageTemplate
+
+get_page_template = GetPageTemplate  # pylint: disable=invalid-name
 
 
 class GetLayoutTemplate(ViewTemplate):
+    """Layout template getter class"""
 
     def __init__(self, name=u''):
+        # pylint: disable=super-init-not-called
         self.provides = ILayoutTemplate
         self.name = name
 
-get_layout_template = GetLayoutTemplate
+
+get_layout_template = GetLayoutTemplate  # pylint: disable=invalid-name
 
 
-class template_config(object):
+class template_config:  # pylint: disable=invalid-name
     """Class decorator used to declare a view template"""
 
     venusian = venusian  # for testing injection
@@ -129,33 +160,34 @@
     def __call__(self, wrapped):
         settings = self.__dict__.copy()
 
-        def callback(context, name, ob):
-            template = os.path.join(os.path.dirname(inspect.getfile(inspect.getmodule(ob))),
+        def callback(context, name, obj):
+            template = os.path.join(os.path.dirname(inspect.getfile(inspect.getmodule(obj))),
                                     settings.get('template'))
             if not os.path.isfile(template):
                 raise ConfigurationError("No such file", template)
 
-            contentType = settings.get('contentType', 'text/html')
+            content_type = settings.get('content_type', 'text/html')
             macro = settings.get('macro')
-            factory = TemplateFactory(template, contentType, macro)
+            factory = TemplateFactory(template, content_type, macro)
             provides = settings.get('provides', IContentTemplate)
             directlyProvides(factory, provides)
 
-            config = context.config.with_package(info.module)
-            config.registry.registerAdapter(factory,
-                                            (ob, settings.get('layer', IRequest)),
-                                            provides, settings.get('name', ''))
+            config = context.config.with_package(info.module)  # pylint: disable=no-member
+            registry = settings.get('registry', config.registry)
+            registry.registerAdapter(factory,
+                                     (obj, settings.get('layer', IRequest)),
+                                     provides, settings.get('name', ''))
 
         info = self.venusian.attach(wrapped, callback, category='pyams_template')
 
-        if info.scope == 'class':
+        if info.scope == 'class':  # pylint: disable=no-member
             # if the decorator was attached to a method in a class, or
             # otherwise executed at class scope, we need to set an
             # 'attr' into the settings if one isn't already in there
             if settings.get('attr') is None:
                 settings['attr'] = wrapped.__name__
 
-        settings['_info'] = info.codeinfo  # fbo "action_method"
+        settings['_info'] = info.codeinfo  # pylint: disable=no-member
         return wrapped
 
 
@@ -170,9 +202,9 @@
                             settings.get('template'))
     if not os.path.isfile(template):
         raise ConfigurationError("No such file", template)
-    contentType = settings.get('contentType', 'text/html')
+    content_type = settings.get('content_type', 'text/html')
     macro = settings.get('macro')
-    factory = TemplateFactory(template, contentType, macro)
+    factory = TemplateFactory(template, content_type, macro)
     provides = settings.get('provides', IContentTemplate)
     directlyProvides(factory, provides)
     registry = getGlobalSiteManager()
@@ -181,7 +213,7 @@
                              provides, settings.get('name', ''))
 
 
-class layout_config(object):
+class layout_config:  # pylint: disable=invalid-name
     """Class decorator used to declare a layout template"""
 
     venusian = venusian  # for testing injection
@@ -201,27 +233,27 @@
             if not os.path.isfile(template):
                 raise ConfigurationError("No such file", template)
 
-            contentType = settings.get('contentType', 'text/html')
+            content_type = settings.get('content_type', 'text/html')
             macro = settings.get('macro')
-            factory = TemplateFactory(template, contentType, macro)
+            factory = TemplateFactory(template, content_type, macro)
             provides = settings.get('provides', ILayoutTemplate)
             directlyProvides(factory, provides)
 
-            config = context.config.with_package(info.module)
+            config = context.config.with_package(info.module)  # pylint: disable=no-member
             config.registry.registerAdapter(factory,
                                             (ob, settings.get('layer', IRequest)),
                                             provides, settings.get('name', ''))
 
         info = self.venusian.attach(wrapped, callback, category='pyams_template')
 
-        if info.scope == 'class':
+        if info.scope == 'class':  # pylint: disable=no-member
             # if the decorator was attached to a method in a class, or
             # otherwise executed at class scope, we need to set an
             # 'attr' into the settings if one isn't already in there
             if settings.get('attr') is None:
                 settings['attr'] = wrapped.__name__
 
-        settings['_info'] = info.codeinfo  # fbo "action_method"
+        settings['_info'] = info.codeinfo  # pylint: disable=no-member
         return wrapped
 
 
@@ -236,9 +268,9 @@
                             settings.get('template'))
     if not os.path.isfile(template):
         raise ConfigurationError("No such file", template)
-    contentType = settings.get('contentType', 'text/html')
+    content_type = settings.get('content_type', 'text/html')
     macro = settings.get('macro')
-    factory = TemplateFactory(template, contentType, macro)
+    factory = TemplateFactory(template, content_type, macro)
     provides = settings.get('provides', ILayoutTemplate)
     directlyProvides(factory, provides)
     registry = getGlobalSiteManager()