26 import sys, os, inspect, copy, struct, dis, imp
31 return ".".
join(name.replace(
"python/",
"").
replace(
".py",
"").
split(
"/")[-3:])
35 """ANSI escape display sequences""" 38 alternate =
"\033[32m" 40 backlight =
"\033[43m" 42 lessemphasis =
"\033[30m" 43 deemphasis =
"\033[1;30m" 60 self.
module = __import__(name,[],[],
"*")
63 print indent,
"+", Color.info, self.
name, Color.none
65 self.dependencies.sort(key =
lambda x: x.name)
69 """ recursive search for pattern in source files""" 72 for number, line
in enumerate(inspect.getsource(self.
module).splitlines()):
78 self.hit.number = number
79 self.hit.filename = filename
81 self.hit.stacks =
list()
82 result.append(self.
hit)
83 self.hit.stacks.append(copy.copy(_stack))
85 _stack.append(self.
name)
87 package.search(pattern,result)
92 class mymf(modulefinder.ModuleFinder):
100 modulefinder.ModuleFinder.__init__(self,*args,**kwargs)
101 def import_hook(self, name, caller=None, fromlist=None, level=-1):
105 return modulefinder.ModuleFinder.import_hook(self,name,caller,fromlist, level=level)
111 if partnam
in (
"os",
"unittest"):
114 r = modulefinder.ModuleFinder.import_module(self,partnam,fqname,parent)
119 r = modulefinder.ModuleFinder.import_module(self,partnam,fqname,parent)
122 self._depgraph.setdefault(self._last_caller.__name__,{})[r.__name__] = 1
125 (suffix, mode, type) = aux_info
126 r = modulefinder.ModuleFinder.load_module(self, fqname, fp, pathname, (suffix, mode, type))
128 self.
_types[r.__name__] = type
133 This is basically just the default opcode scanner from ModuleFinder, but extended to also 134 look for "process.load(<module>)' commands. Since the Process object might not necassarily 135 be called "process", it scans for a call to a "load" method with a single parameter on 136 *any* object. If one is found it checks if the parameter is a string that refers to a valid 137 python module in the local or global area. If it does, the scanner assumes this was a call 138 to a Process object and yields the module name. 139 It's not possible to scan first for Process object declarations to get the name of the 140 objects since often (e.g. for customisation functions) the object is passed to a function 143 The ModuleFinder.scan_opcodes_25 implementation this is based was taken from 144 https://hg.python.org/cpython/file/2.7/Lib/modulefinder.py#l364 150 consts = co.co_consts
151 LOAD_CONST = modulefinder.LOAD_CONST
152 IMPORT_NAME = modulefinder.IMPORT_NAME
153 STORE_OPS = modulefinder.STORE_OPS
154 HAVE_ARGUMENT = modulefinder.HAVE_ARGUMENT
155 LOAD_ATTR = chr(dis.opname.index(
'LOAD_ATTR'))
156 LOAD_NAME = chr(dis.opname.index(
'LOAD_NAME'))
157 CALL_FUNCTION = chr(dis.opname.index(
'CALL_FUNCTION'))
158 LOAD_LOAD_AND_IMPORT = LOAD_CONST + LOAD_CONST + IMPORT_NAME
161 indexOfLoadConst = names.index(
"load")
164 loadMethodOpcodes = LOAD_ATTR+struct.pack(
'<H',indexOfLoadConst)
167 loadMethodOpcodes=
None 173 if loadMethodOpcodes!=
None and len(code)>=9 :
174 if code[:3]==loadMethodOpcodes :
179 if code[6]==CALL_FUNCTION :
183 indexInTable=
unpack(
'<H',code[4:6])[0]
184 if code[3]==LOAD_CONST :
186 loadMethodArgument=consts[indexInTable]
191 loadMethodArgument = loadMethodArgument.replace(
"/",
".")
199 for subModule
in loadMethodArgument.split(
".") :
200 moduleInfo=imp.find_module( subModule, parentFilename )
201 parentFilename=[moduleInfo[1]]
203 yield "import", (
None, loadMethodArgument)
207 for subModule
in loadMethodArgument.split(
".") :
208 moduleInfo=imp.find_module( subModule, parentFilename )
209 parentFilename=[moduleInfo[1]]
211 yield "import", (
None, loadMethodArgument)
212 except Exception
as error:
218 elif code[3]==LOAD_NAME :
222 print "Unable to determine the value of variable '"+names[indexInTable]+
"' to see if it is a proces.load(...) statement in file "+co.co_filename
228 oparg, =
unpack(
'<H', code[1:3])
229 yield "store", (names[oparg],)
232 if code[:9:3] == LOAD_LOAD_AND_IMPORT:
233 oparg_1, oparg_2, oparg_3 =
unpack(
'<xHxHxH', code[:9])
234 level = consts[oparg_1]
236 yield "import", (consts[oparg_2], names[oparg_3])
238 yield "absolute_import", (consts[oparg_2], names[oparg_3])
240 yield "relative_import", (level, consts[oparg_2], names[oparg_3])
243 if c >= HAVE_ARGUMENT:
249 if currentStack
is None : currentStack=[]
251 duplicateIndex=currentStack.index( node )
253 print "Removing recursive loop in:" 254 for index
in xrange(duplicateIndex,len(currentStack)) :
255 print " ",currentStack[index].name,
"-->" 257 currentStack[-1].dependencies.remove(node)
260 currentStack.append( node )
261 for subnode
in node.dependencies :
267 packageDict[toplevel] =
Package(toplevel, top =
True)
270 for key, value
in six.iteritems(depgraph):
271 if key.count(
".") == 2
and key != toplevel:
272 packageDict[key] =
Package(key)
273 for name
in value.keys():
274 if name.count(
".") == 2: packageDict[name] =
Package(name)
276 for key, value
in six.iteritems(depgraph):
277 if key.count(
".") == 2
or key == toplevel:
278 package = packageDict[key]
279 package.dependencies = [packageDict[name]
for name
in value.keys()
if name.count(
".") == 2]
283 return packageDict[toplevel]
287 modulefinder =
mymf(path)
288 modulefinder.run_script(filename)
289 globalDependencyDict = modulefinder._depgraph
290 globalDependencyDict[toplevelname] = globalDependencyDict[
"__main__"]
291 return globalDependencyDict
301 return dependencyGraph
def import_hook(self, name, caller=None, fromlist=None, level=-1)
def replace(string, replacements)
def __init__(self, name, top=False)
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