00001 #!/usr/local/bin/python 00002 # 00003 # Copyright 2002 00004 # by 00005 # The Board of Trustees of the 00006 # Leland Stanford Junior University. 00007 # All rights reserved. 00008 # 00009 00010 __facility__ = "Online" 00011 __abstract__ = "GLAST LAT run control related utility methods" 00012 __author__ = "S. Tuvi <stuvi@SLAC.Stanford.edu> SLAC - GLAST LAT I&T/Online" 00013 __date__ = ("$Date: 2005/03/30 05:59:08 $").split(' ')[1] 00014 __version__ = "$Revision: 2.12 $" 00015 __credits__ = "SLAC" 00016 00017 import LATTE.copyright_SLAC 00018 00019 import imp 00020 import os 00021 import sys 00022 import logging as log 00023 import string 00024 from types import ModuleType 00025 00026 class Reloader: 00027 DONT_RELOAD_LIST = ['scipy', 'weave', 'qwt', 'xml', 'pyexpat', 'win32', 00028 'ROOT', 'libPyROOT'] 00029 00030 def __init__(self): 00031 self.appinit = {} 00032 00033 def getNewModules(self, keepem): 00034 modules = {} 00035 for i, m in sys.modules.items(): 00036 if (i not in keepem) and \ 00037 (type(m) == ModuleType): 00038 modules[i] = m 00039 return modules 00040 00041 def clearAppModules(self, dontReloadList, showUnloadedModules): 00042 if self.appinit == {}: 00043 appfinish = {} 00044 else: 00045 appfinish = self.getNewModules(self.appinit) 00046 for i in self.filterModules(appfinish, dontReloadList): 00047 if i in sys.modules: 00048 if showUnloadedModules: 00049 log.debug("Unloading module %s %s" % (i, sys.modules[i].__file__)) 00050 del sys.modules[i] 00051 self.appinit = sys.modules.copy() 00052 00053 def filterModules(self, modules, dontReloadList): 00054 dontReload = dontReloadList + Reloader.DONT_RELOAD_LIST 00055 mods = [] 00056 for (moduleName, module) in modules.items(): 00057 for modulePrefix in dontReload: 00058 if moduleName.startswith(modulePrefix): 00059 break 00060 if '__file__' not in dir(module): 00061 break 00062 if os.path.splitext(module.__file__)[1].lower() in ('.pyd','.dll'): 00063 break 00064 if os.path.normpath(os.path.normcase(module.__file__)).startswith(os.path.normpath(os.path.normcase(sys.prefix))): 00065 break 00066 else: 00067 mods.append(moduleName) 00068 return mods 00069 00070 reloadModules = Reloader() 00071 00072 def importModule(appName, reload=1, dontReloadList=[], showUnloadedModules=0): 00073 """Import a RunControl application or suite 00074 \param appName Name of the module or pathname of the python script 00075 \param reload 1 = Reload all modules that have been loaded since RunControl started (default) 00076 0 = Do not reload modules (used if a suite is being loaded) 00077 \param dontReloadList Optional parameter which specifies the additional list of module prefixes 00078 that should not be reloaded. If this parameter is missing then the default list 00079 (Reloader.DONT_RELOAD_LIST) is used, if it is specified then it gets appended 00080 to the default list. 00081 00082 \return The name of the module and the resolved pathname 00083 00084 """ 00085 00086 # First check if a module name is specified, if so try to resolve its source. 00087 (appPath, appFile) = os.path.split(appName) 00088 (appBase, appExt) = os.path.splitext(appFile) 00089 if appExt == '': 00090 try: 00091 if appPath == '': 00092 (f, path, desc) = imp.find_module(appBase) 00093 else: 00094 (f, path, desc) = imp.find_module(appBase, [appPath]) 00095 (appPath, appFile) = os.path.split(path) 00096 (appBase, appExt) = os.path.splitext(appFile) 00097 except ImportError, e: 00098 raise e 00099 00100 _suffixes = {} 00101 for ext, mode, typ in imp.get_suffixes(): 00102 _suffixes[ext] = (ext, mode, typ) 00103 _infoMap = { 00104 '.py' : ('.py','r',1), 00105 '.pyc': ('.pyc','rb',2), 00106 '.pyo': ('.pyo','rb',2) 00107 } 00108 00109 00110 # Temporarily change the directory in case the application 00111 # needs to load additional modules from the same directory. 00112 curDir = os.getcwd() 00113 if appPath != '': os.chdir(appPath) 00114 00115 # Handle relative paths, by resolving the path again after current directory is changed. 00116 appPath = os.getcwd() 00117 if appPath not in sys.path: 00118 sys.path.append(appPath) 00119 appName = os.path.join(appPath, appFile) 00120 00121 pycFile = os.path.join(appPath, appBase + '.pyc') 00122 pyoFile = os.path.join(appPath, appBase + '.pyo') 00123 if appExt == '.py': 00124 if os.path.exists(pyoFile) and os.path.getmtime(pyoFile) >= os.path.getmtime(appName): 00125 filename = pyoFile 00126 appExt = '.pyo' 00127 elif _suffixes.has_key('.pyo'): 00128 filename = appName 00129 elif os.path.exists(pycFile) and os.path.getmtime(pycFile) >= os.path.getmtime(appName): 00130 filename = pycFile 00131 appExt = '.pyc' 00132 else: 00133 filename = appName 00134 elif appExt == '.pyc': 00135 if os.path.exists(pyoFile) and os.path.getmtime(pyoFile) >= os.path.getmtime(appName): 00136 filename = pyoFile 00137 appExt = '.pyo' 00138 else: 00139 filename = appName 00140 elif appExt == '.pyo': 00141 filename = appName 00142 else: 00143 msg = 'Invalid module extension: %s' % appName 00144 raise RuntimeError, msg 00145 info = _infoMap[appExt] 00146 f = file(filename, info[1]) 00147 00148 try: 00149 # Clear the modules that was imported during the loading and 00150 # execution of the previous script. 00151 if reload: reloadModules.clearAppModules(dontReloadList, showUnloadedModules) 00152 module = imp.load_module(appBase, f, filename, info) 00153 finally: 00154 f.close() 00155 sys.path.remove(appPath) 00156 if os.path.exists(curDir): 00157 os.chdir(curDir) 00158 return (module, filename)