0001"""Kid Import Hooks.
0002
0003When installed, these hooks allow importing .kid files as if they were
0004Python modules.
0005
0006"""
0007
0008__revision__ = "$Rev: 317 $"
0009__date__ = "$Date: 2006-04-21 08:51:24 +0000 (Fri, 21 Apr 2006) $"
0010__author__ = "Ryan Tomayko (rtomayko@gmail.com)"
0011__copyright__ = "Copyright 2004-2005, Ryan Tomayko"
0012__license__ = "MIT <http://www.opensource.org/licenses/mit-license.php>"
0013
0014import os, sys, time, new
0015import __builtin__
0016
0017import kid.compiler
0018KID_EXT = kid.compiler.KID_EXT
0019
0020assert sys.hexversion >= 0x20000b1, "need Python 2.0b1 or later"
0021
0022_installed = False
0023
0024def install(suffixes=None):
0025 global _installed
0026 if not _installed:
0027 _install_hook(suffixes=suffixes)
0028 _installed = True
0029
0030def uninstall():
0031 global _installed
0032 if _installed:
0033 _uninstall_hook()
0034 _installed = False
0035
0036def import_template(name, filename, force=0):
0037 if not force and name and sys.modules.has_key(name):
0038 return sys.modules[name]
0039 template = kid.compiler.KidFile(filename)
0040 code = template.compile(dump_source=os.environ.get('KID_OUTPUT_PY'))
0041 module = _create_module(code, name, filename)
0042 return module
0043
0044def get_template_name(name, filename):
0045 if name:
0046 return name
0047 else:
0048 return 'kid.util.template_%x' % (hash(filename) + sys.maxint + 1)
0049
0050def _create_module(code, name, filename, store=1, ns={}):
0051 name = get_template_name(name, filename)
0052 mod = new.module(name)
0053 mod.__file__ = filename
0054 mod.__ctime__ = time.time()
0055 mod.__dict__.update(ns)
0056 exec code in mod.__dict__
0057 if store:
0058 sys.modules[name] = mod
0059 return mod
0060
0061
0062KID_FILE = object()
0063
0064try:
0065 from sys import path_hooks, path_importer_cache
0066except ImportError:
0067 path_hooks = None
0068
0069if path_hooks is not None:
0070
0071 class KIDLoader(object):
0072
0073 def __init__(self, path=None):
0074 if path and os.path.isdir(path):
0075 self.path = path
0076 else:
0077 raise ImportError
0078
0079 def find_module(self, fullname):
0080 path = os.path.join(self.path, fullname.split('.')[-1])
0081 for ext in [KID_EXT] + self.suffixes:
0082 if os.path.exists(path + ext):
0083 self.filename = path + ext
0084 return self
0085 return None
0086
0087 def load_module(self, fullname):
0088 return import_template(fullname, self.filename, force=1)
0089
0090 def _install_hook(suffixes=None):
0091 KIDLoader.suffixes = suffixes or []
0092 path_hooks.append(KIDLoader)
0093 sys.path_importer_cache.clear()
0094
0095 def _uninstall_hook():
0096 i = 0
0097 while i < len(path_hooks):
0098 if path_hooks[i] is KIDLoader:
0099 del path_hooks[i]
0100 else:
0101 i += 1
0102 sys.path_importer_cache.clear()
0103
0104else:
0105
0106 import ihooks, imp
0107
0108 class KIDHooks(ihooks.Hooks):
0109
0110 def __init__(self, verbose=ihooks.VERBOSE, suffixes=None):
0111 ihooks.Hooks.__init__(self, verbose)
0112 self.suffixes = suffixes or []
0113
0114 def get_suffixes(self):
0115 return [(suffix, 'r', KID_FILE)
0116 for suffix in [KID_EXT] + self.suffixes] + imp.get_suffixes()
0117
0118 class KIDLoader(ihooks.ModuleLoader):
0119
0120 def load_module(self, name, stuff):
0121 file, filename, info = stuff
0122 (suff, mode, type) = info
0123 if type is KID_FILE:
0124 return import_template(name, filename, force=1)
0125 else:
0126 return ihooks.ModuleLoader.load_module(self, name, stuff)
0127
0128 def _install_hook(suffixes=None):
0129 hooks = KIDHooks(suffixes=suffixes)
0130 loader = KIDLoader(hooks)
0131 importer = ihooks.ModuleImporter(loader)
0132 ihooks.install(importer)
0133
0134 def _uninstall_hook():
0135 ihooks.uninstall()