Edgewall Software

Ticket #412: loader.patch

File loader.patch, 7.0 KB (added by Christoph Zwerschke <cito@…>, 13 years ago)

suggested patch for genshi.template.loader

  • genshi/template/loader.py

     
    1414"""Template loading and caching."""
    1515
    1616import os
     17import sys
    1718try:
    1819    import threading
    1920except ImportError:
     
    3233
    3334    def __init__(self, name, search_path):
    3435        """Create the exception.
    35        
     36
    3637        :param name: the filename of the template
    3738        :param search_path: the search path used to lookup the template
    3839        """
     
    4344class TemplateLoader(object):
    4445    """Responsible for loading templates from files on the specified search
    4546    path.
    46    
     47
    4748    >>> import tempfile
    4849    >>> fd, path = tempfile.mkstemp(suffix='.html', prefix='template')
    4950    >>> os.write(fd, '<p>$var</p>')
    5051    11
    5152    >>> os.close(fd)
    52    
     53
    5354    The template loader accepts a list of directory paths that are then used
    5455    when searching for template files, in the given order:
    55    
     56
    5657    >>> loader = TemplateLoader([os.path.dirname(path)])
    57    
     58
    5859    The `load()` method first checks the template cache whether the requested
    5960    template has already been loaded. If not, it attempts to locate the
    6061    template file, and returns the corresponding `Template` object:
    61    
     62
    6263    >>> from genshi.template import MarkupTemplate
    6364    >>> template = loader.load(os.path.basename(path))
    6465    >>> isinstance(template, MarkupTemplate)
    6566    True
    66    
     67
    6768    Template instances are cached: requesting a template with the same name
    6869    results in the same instance being returned:
    69    
     70
    7071    >>> loader.load(os.path.basename(path)) is template
    7172    True
    72    
     73
    7374    The `auto_reload` option can be used to control whether a template should
    7475    be automatically reloaded when the file it was loaded from has been
    7576    changed. Disable this automatic reloading to improve performance.
    76    
     77
    7778    >>> os.remove(path)
    7879    """
    7980    def __init__(self, search_path=None, auto_reload=False,
    8081                 default_encoding=None, max_cache_size=25, default_class=None,
    8182                 variable_lookup='strict', allow_exec=True, callback=None):
    8283        """Create the template laoder.
    83        
     84
    8485        :param search_path: a list of absolute path names that should be
    8586                            searched for template files, or a string containing
    8687                            a single absolute path; alternatively, any item on
     
    105106                         callback can be used for example to add any desired
    106107                         filters to the template
    107108        :see: `LenientLookup`, `StrictLookup`
    108        
     109
    109110        :note: Changed in 0.5: Added the `allow_exec` argument
    110111        """
    111112        from genshi.template.markup import MarkupTemplate
     
    142143
    143144    def load(self, filename, relative_to=None, cls=None, encoding=None):
    144145        """Load the template with the given name.
    145        
     146
    146147        If the `filename` parameter is relative, this method searches the
    147148        search path trying to locate a template matching the given name. If the
    148149        file name is an absolute path, the search path is ignored.
    149        
     150
    150151        If the requested template is not found, a `TemplateNotFound` exception
    151152        is raised. Otherwise, a `Template` object is returned that represents
    152153        the parsed template.
    153        
     154
    154155        Template instances are cached to avoid having to parse the same
    155156        template file more than once. Thus, subsequent calls of this method
    156157        with the same template file name will return the same `Template`
    157158        object (unless the ``auto_reload`` option is enabled and the file was
    158159        changed since the last parse.)
    159        
     160
    160161        If the `relative_to` parameter is provided, the `filename` is
    161162        interpreted as being relative to that path.
    162        
     163
    163164        :param filename: the relative path of the template file to load
    164165        :param relative_to: the filename of the template from which the new
    165166                            template is being loaded, or ``None`` if the
     
    226227                else:
    227228                    try:
    228229                        if isabs:
    229                             # If the filename of either the included or the 
     230                            # If the filename of either the included or the
    230231                            # including template is absolute, make sure the
    231232                            # included template gets an absolute path, too,
    232233                            # so that nested includes work properly without a
     
    251252    def _instantiate(self, cls, fileobj, filepath, filename, encoding=None):
    252253        """Instantiate and return the `Template` object based on the given
    253254        class and parameters.
    254        
     255
    255256        This function is intended for subclasses to override if they need to
    256257        implement special template instantiation logic. Code that just uses
    257258        the `TemplateLoader` should use the `load` method instead.
    258        
     259
    259260        :param cls: the class of the template object to instantiate
    260261        :param fileobj: a readable file-like object containing the template
    261262                        source
     
    276277    @staticmethod
    277278    def directory(path):
    278279        """Loader factory for loading templates from a local directory.
    279        
     280
    280281        :param path: the path to the local directory containing the templates
    281282        :return: the loader function to load templates from the given directory
    282283        :rtype: ``function``
    283284        """
     285        if os.path.supports_unicode_filenames and not isinstance(path, unicode):
     286            encoding = sys.getfilesystemencoding()
     287            if encoding:
     288                path = unicode(path, encoding)
     289            else:
     290                path = unicode(path)
    284291        def _load_from_directory(filename):
    285292            filepath = os.path.join(path, filename)
    286293            fileobj = open(filepath, 'U')
     
    293300    @staticmethod
    294301    def package(name, path):
    295302        """Loader factory for loading templates from egg package data.
    296        
     303
    297304        :param name: the name of the package containing the resources
    298305        :param path: the path inside the package data
    299306        :return: the loader function to load templates from the given package
     
    309316    def prefixed(**delegates):
    310317        """Factory for a load function that delegates to other loaders
    311318        depending on the prefix of the requested template path.
    312        
     319
    313320        The prefix is stripped from the filename when passing on the load
    314321        request to the delegate.
    315        
     322
    316323        >>> load = prefixed(
    317324        ...     app1 = lambda filename: ('app1', filename, None, None),
    318325        ...     app2 = lambda filename: ('app2', filename, None, None)
     
    321328        ('app1', 'app1/foo.html', None, None)
    322329        >>> print(load('app2/bar.html'))
    323330        ('app2', 'app2/bar.html', None, None)
    324        
     331
    325332        :param delegates: mapping of path prefixes to loader functions
    326333        :return: the loader function
    327334        :rtype: ``function``