1 from __future__
import print_function
27 import sys, os, inspect, copy, struct, dis, imp
32 return ".".
join(name.replace(
"python/",
"").
replace(
".py",
"").
split(
"/")[-3:])
36 """ANSI escape display sequences""" 39 alternate =
"\033[32m" 41 backlight =
"\033[43m" 43 lessemphasis =
"\033[30m" 44 deemphasis =
"\033[1;30m" 61 self.
module = __import__(name,[],[],
"*")
64 print(indent,
"+", Color.info, self.
name, Color.none)
66 self.dependencies.sort(key =
lambda x: x.name)
70 """ recursive search for pattern in source files""" 73 for number, line
in enumerate(inspect.getsource(self.
module).splitlines()):
79 self.hit.number = number
80 self.hit.filename = filename
82 self.hit.stacks =
list()
83 result.append(self.
hit)
84 self.hit.stacks.append(copy.copy(_stack))
86 _stack.append(self.
name)
88 package.search(pattern,result)
93 class mymf(modulefinder.ModuleFinder):
101 modulefinder.ModuleFinder.__init__(self,*args,**kwargs)
102 def import_hook(self, name, caller=None, fromlist=None, level=-1):
106 return modulefinder.ModuleFinder.import_hook(self,name,caller,fromlist, level=level)
112 if partnam
in (
"os",
"unittest"):
115 r = modulefinder.ModuleFinder.import_module(self,partnam,fqname,parent)
120 r = modulefinder.ModuleFinder.import_module(self,partnam,fqname,parent)
123 self._depgraph.setdefault(self._last_caller.__name__,{})[r.__name__] = 1
126 (suffix, mode, type) = aux_info
127 r = modulefinder.ModuleFinder.load_module(self, fqname, fp, pathname, (suffix, mode, type))
129 self.
_types[r.__name__] = type
134 This is basically just the default opcode scanner from ModuleFinder, but extended to also 135 look for "process.load(<module>)' commands. Since the Process object might not necassarily 136 be called "process", it scans for a call to a "load" method with a single parameter on 137 *any* object. If one is found it checks if the parameter is a string that refers to a valid 138 python module in the local or global area. If it does, the scanner assumes this was a call 139 to a Process object and yields the module name. 140 It's not possible to scan first for Process object declarations to get the name of the 141 objects since often (e.g. for customisation functions) the object is passed to a function 144 The ModuleFinder.scan_opcodes_25 implementation this is based was taken from 145 https://hg.python.org/cpython/file/2.7/Lib/modulefinder.py#l364 151 consts = co.co_consts
152 LOAD_CONST = modulefinder.LOAD_CONST
153 IMPORT_NAME = modulefinder.IMPORT_NAME
154 STORE_OPS = modulefinder.STORE_OPS
155 HAVE_ARGUMENT = modulefinder.HAVE_ARGUMENT
156 LOAD_ATTR = chr(dis.opname.index(
'LOAD_ATTR'))
157 LOAD_NAME = chr(dis.opname.index(
'LOAD_NAME'))
158 CALL_FUNCTION = chr(dis.opname.index(
'CALL_FUNCTION'))
159 LOAD_LOAD_AND_IMPORT = LOAD_CONST + LOAD_CONST + IMPORT_NAME
162 indexOfLoadConst = names.index(
"load")
165 loadMethodOpcodes = LOAD_ATTR+struct.pack(
'<H',indexOfLoadConst)
168 loadMethodOpcodes=
None 174 if loadMethodOpcodes!=
None and len(code)>=9 :
175 if code[:3]==loadMethodOpcodes :
180 if code[6]==CALL_FUNCTION :
184 indexInTable=
unpack(
'<H',code[4:6])[0]
185 if code[3]==LOAD_CONST :
187 loadMethodArgument=consts[indexInTable]
192 loadMethodArgument = loadMethodArgument.replace(
"/",
".")
200 for subModule
in loadMethodArgument.split(
".") :
201 moduleInfo=imp.find_module( subModule, parentFilename )
202 parentFilename=[moduleInfo[1]]
204 yield "import", (
None, loadMethodArgument)
208 for subModule
in loadMethodArgument.split(
".") :
209 moduleInfo=imp.find_module( subModule, parentFilename )
210 parentFilename=[moduleInfo[1]]
212 yield "import", (
None, loadMethodArgument)
213 except Exception
as error:
219 elif code[3]==LOAD_NAME :
223 print(
"Unable to determine the value of variable '"+names[indexInTable]+
"' to see if it is a proces.load(...) statement in file "+co.co_filename)
229 oparg, =
unpack(
'<H', code[1:3])
230 yield "store", (names[oparg],)
233 if code[:9:3] == LOAD_LOAD_AND_IMPORT:
234 oparg_1, oparg_2, oparg_3 =
unpack(
'<xHxHxH', code[:9])
235 level = consts[oparg_1]
237 yield "import", (consts[oparg_2], names[oparg_3])
239 yield "absolute_import", (consts[oparg_2], names[oparg_3])
241 yield "relative_import", (level, consts[oparg_2], names[oparg_3])
244 if c >= HAVE_ARGUMENT:
250 if currentStack
is None : currentStack=[]
252 duplicateIndex=currentStack.index( node )
254 print(
"Removing recursive loop in:")
255 for index
in xrange(duplicateIndex,len(currentStack)) :
256 print(
" ",currentStack[index].name,
"-->")
258 currentStack[-1].dependencies.remove(node)
261 currentStack.append( node )
262 for subnode
in node.dependencies :
268 packageDict[toplevel] =
Package(toplevel, top =
True)
271 for key, value
in six.iteritems(depgraph):
272 if key.count(
".") == 2
and key != toplevel:
273 packageDict[key] =
Package(key)
274 for name
in value.keys():
275 if name.count(
".") == 2: packageDict[name] =
Package(name)
277 for key, value
in six.iteritems(depgraph):
278 if key.count(
".") == 2
or key == toplevel:
279 package = packageDict[key]
280 package.dependencies = [packageDict[name]
for name
in value.keys()
if name.count(
".") == 2]
284 return packageDict[toplevel]
288 modulefinder =
mymf(path)
289 modulefinder.run_script(filename)
290 globalDependencyDict = modulefinder._depgraph
291 globalDependencyDict[toplevelname] = globalDependencyDict[
"__main__"]
292 return globalDependencyDict
302 return dependencyGraph
def import_hook(self, name, caller=None, fromlist=None, level=-1)
def replace(string, replacements)
def __init__(self, name, top=False)
S & print(S &os, JobReport::InputFile const &f)
def getDependenciesFromPythonFile(filename, toplevelname, path)
def __init__(self, args, kwargs)
def import_module(self, partnam, fqname, parent)
def getImportTree(filename, path)
def packageNameFromFilename(name)
static std::string join(char **cmd)
def removeRecursiveLoops(node, verbose=False, currentStack=None)
def search(self, pattern, result)
def transformIntoGraph(depgraph, toplevel)
def scan_opcodes_25(self, co, unpack=struct.unpack)
def load_module(self, fqname, fp, pathname, aux_info)
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger list("!*","!HLTx*"if it matches 2 triggers or more) will accept the event if all the matching triggers are FAIL.It will reject the event if any of the triggers are PASS or EXCEPTION(this matches the behavior of"!*"before the partial wildcard feature was incorporated).Triggers which are in the READY state are completely ignored.(READY should never be returned since the trigger paths have been run