o !b9@sdZddlZzddlZWn eyddlZYnwddlZddlmZddlm Z gdZ dZ GdddeZ Gd d d e ZejZejZejZdS) zTemplate loading and caching.N) TemplateError)LRUCache)TemplateLoaderTemplateNotFound directorypackageprefixedzrestructuredtext enc@seZdZdZddZdS)rzBException raised when a specific template file could not be found.cCst|d|||_dS)zCreate the exception. :param name: the filename of the template :param search_path: the search path used to lookup the template zTemplate "%s" not foundN)r__init__ search_path)selfnamer r 8/usr/lib/python3/dist-packages/genshi/template/loader.pyr #s zTemplateNotFound.__init__N)__name__ __module__ __qualname____doc__r r r r rr s rc@sheZdZdZ   dddZd d Zd d Zdd dZdddZe ddZ e ddZ e ddZ dS)raResponsible for loading templates from files on the specified search path. >>> import tempfile >>> fd, path = tempfile.mkstemp(suffix='.html', prefix='template') >>> os.write(fd, u'

$var

'.encode('utf-8')) 11 >>> os.close(fd) The template loader accepts a list of directory paths that are then used when searching for template files, in the given order: >>> loader = TemplateLoader([os.path.dirname(path)]) The `load()` method first checks the template cache whether the requested template has already been loaded. If not, it attempts to locate the template file, and returns the corresponding `Template` object: >>> from genshi.template import MarkupTemplate >>> template = loader.load(os.path.basename(path)) >>> isinstance(template, MarkupTemplate) True Template instances are cached: requesting a template with the same name results in the same instance being returned: >>> loader.load(os.path.basename(path)) is template True The `auto_reload` option can be used to control whether a template should be automatically reloaded when the file it was loaded from has been changed. Disable this automatic reloading to improve performance. >>> os.remove(path) NFstrictTc Csddlm} ||_|jdurg|_n t|jttfs|jg|_||_ ||_|p)| |_||_ ||_ |dur>t |ds>t d||_ t||_i|_t|_dS)aCreate the template laoder. :param search_path: a list of absolute path names that should be searched for template files, or a string containing a single absolute path; alternatively, any item on the list may be a ''load function'' that is passed a filename and returns a file-like object and some metadata :param auto_reload: whether to check the last modification time of template files, and reload them if they have changed :param default_encoding: the default encoding to assume when loading templates; defaults to UTF-8 :param max_cache_size: the maximum number of templates to keep in the cache :param default_class: the default `Template` subclass to use when instantiating templates :param variable_lookup: the variable lookup mechanism; either "strict" (the default), "lenient", or a custom lookup class :param allow_exec: whether to allow Python code blocks in templates :param callback: (optional) a callback function that is invoked after a template was initialized by this loader; the function is passed the template object as only argument. This callback can be used for example to add any desired filters to the template :see: `LenientLookup`, `StrictLookup` :note: Changed in 0.5: Added the `allow_exec` argument r)MarkupTemplateN__call__z-The "callback" parameter needs to be callable)genshi.template.markuprr isinstancelisttuple auto_reloaddefault_encoding default_classvariable_lookup allow_exechasattr TypeErrorcallbackr_cache _uptodate threadingRLock_lock) r r rrmax_cache_sizerrrr"rr r rr Qs$     zTemplateLoader.__init__cCs|j}d|d<|S)Nr')__dict__copyr stater r r __getstate__s zTemplateLoader.__getstate__cCs||_t|_dSN)r)r%r&r'r+r r r __setstate__szTemplateLoader.__setstate__c Cs|dur|j}|j}|r|rtj|stjtj||}tj|}|}|j zz(|j |}|j s?|WW|j S|j |}|durT|rT|WW|j SWn ttfy`Ynwd} tj|rstj|g}d} n"|rtj|rtj|} | |vrt|| g}d} n|std|D]`} t| tjrt| } z | |\} }} }Wn tyYqwz+| r| }|j|| | ||d}|jr||||j |<||j |<Wt| dr| n t| dr| ww|W|j St|||j w)a[Load the template with the given name. If the `filename` parameter is relative, this method searches the search path trying to locate a template matching the given name. If the file name is an absolute path, the search path is ignored. If the requested template is not found, a `TemplateNotFound` exception is raised. Otherwise, a `Template` object is returned that represents the parsed template. Template instances are cached to avoid having to parse the same template file more than once. Thus, subsequent calls of this method with the same template file name will return the same `Template` object (unless the ``auto_reload`` option is enabled and the file was changed since the last parse.) If the `relative_to` parameter is provided, the `filename` is interpreted as being relative to that path. :param filename: the relative path of the template file to load :param relative_to: the filename of the template from which the new template is being loaded, or ``None`` if the template is being loaded directly :param cls: the class of the template object to instantiate :param encoding: the encoding of the template to load; defaults to the ``default_encoding`` of the loader instance :return: the loaded `Template` instance :raises TemplateNotFound: if a template with the given name could not be found NFTz(Search path for templates not configured)encodingclose)rr ospathisabsjoindirnamenormpathr'acquirer#rreleaser$KeyErrorOSErrorrrrsix string_typesrIOError _instantiater"r r1r)r filename relative_toclsr0r cachekeytmpluptodater4r6loadfuncfilepathfileobjr r rloadsz    8  5            zTemplateLoader.loadc Cs(|dur|j}|||||||j|jdS)aInstantiate and return the `Template` object based on the given class and parameters. This function is intended for subclasses to override if they need to implement special template instantiation logic. Code that just uses the `TemplateLoader` should use the `load` method instead. :param cls: the class of the template object to instantiate :param fileobj: a readable file-like object containing the template source :param filepath: the absolute path to the template file :param filename: the path to the template file relative to the search path :param encoding: the encoding of the template to load; defaults to the ``default_encoding`` of the loader instance :return: the loaded `Template` instance :rtype: `Template` N)rGr@loaderr0lookupr)rrr)r rBrHrGr@r0r r rr?s  zTemplateLoader._instantiatecfdd}|S)a Loader factory for loading templates from a local directory. :param path: the path to the local directory containing the templates :return: the loader function to load templates from the given directory :rtype: ``function`` cs>tj|td}tjfdd}|||fS)NrbcstjkSr.)r2r3getmtimer rGmtimer rr$"szITemplateLoader.directory.._load_from_directory.._uptodate)r2r3r5openrN)r@rHr$r3rOr_load_from_directorys    z6TemplateLoader.directory.._load_from_directoryr )r3rSr rRrrs zTemplateLoader.directorycs ddlmfdd}|S)a4Loader factory for loading templates from egg package data. :param name: the name of the package containing the resources :param path: the path inside the package data :return: the loader function to load templates from the given package :rtype: ``function`` r)resource_streamcs tj|}|||dfSr.)r2r3r5)r@rGr r3rTr r_load_from_package1sz2TemplateLoader.package.._load_from_package) pkg_resourcesrT)r r3rVr rUrr's zTemplateLoader.packagec rL)aFactory for a load function that delegates to other loaders depending on the prefix of the requested template path. The prefix is stripped from the filename when passing on the load request to the delegate. >>> load = prefixed( ... app1 = lambda filename: ('app1', filename, None, None), ... app2 = lambda filename: ('app2', filename, None, None) ... ) >>> print(load('app1/foo.html')) ('app1', 'app1/foo.html', None, None) >>> print(load('app2/bar.html')) ('app2', 'app2/bar.html', None, None) :param delegates: mapping of path prefixes to loader functions :return: the loader function :rtype: ``function`` cstD],\}}||r0t|tjrt|}||t|dd\}}}}||||fSqt|t )Nz/\) items startswithrr<r=rlenlstriprrkeys)r@prefixdelegaterG_rHrE delegatesr r_dispatch_by_prefixKs   z4TemplateLoader.prefixed.._dispatch_by_prefixr )rarbr r`rr6s  zTemplateLoader.prefixed)NFNrNrTN)NNNr.) rrrrr r-r/rIr? staticmethodrrrr r r rr-s # 7  l  r)rr2r% ImportErrordummy_threadingr<genshi.template.baser genshi.utilr__all__ __docformat__robjectrrrrr r r rs&       -