1 from __future__
import print_function
27 from builtins
import range
28 import sys, os, inspect, copy, struct, dis, imp
33 return ".".
join(name.replace(
"python/",
"").
replace(
".py",
"").
split(
"/")[-3:])
37 """ANSI escape display sequences""" 40 alternate =
"\033[32m" 42 backlight =
"\033[43m" 44 lessemphasis =
"\033[30m" 45 deemphasis =
"\033[1;30m" 62 self.
module = __import__(name,[],[],
"*")
65 print(indent,
"+", Color.info, self.
name, Color.none)
67 self.dependencies.sort(key =
lambda x: x.name)
71 """ recursive search for pattern in source files""" 74 for number, line
in enumerate(inspect.getsource(self.
module).splitlines()):
80 self.hit.number = number
81 self.hit.filename = filename
83 self.hit.stacks =
list()
84 result.append(self.
hit)
85 self.hit.stacks.append(copy.copy(_stack))
87 _stack.append(self.
name)
89 package.search(pattern,result)
94 class mymf(modulefinder.ModuleFinder):
102 modulefinder.ModuleFinder.__init__(self,*args,**kwargs)
103 def import_hook(self, name, caller=None, fromlist=None, level=-1):
107 return modulefinder.ModuleFinder.import_hook(self,name,caller,fromlist, level=level)
113 if partnam
in (
"os",
"unittest"):
116 r = modulefinder.ModuleFinder.import_module(self,partnam,fqname,parent)
121 r = modulefinder.ModuleFinder.import_module(self,partnam,fqname,parent)
124 self._depgraph.setdefault(self._last_caller.__name__,{})[r.__name__] = 1
127 (suffix, mode, type) = aux_info
128 r = modulefinder.ModuleFinder.load_module(self, fqname, fp, pathname, (suffix, mode, type))
130 self.
_types[r.__name__] = type
135 This is basically just the default opcode scanner from ModuleFinder, but extended to also 136 look for "process.load(<module>)' commands. Since the Process object might not necassarily 137 be called "process", it scans for a call to a "load" method with a single parameter on 138 *any* object. If one is found it checks if the parameter is a string that refers to a valid 139 python module in the local or global area. If it does, the scanner assumes this was a call 140 to a Process object and yields the module name. 141 It's not possible to scan first for Process object declarations to get the name of the 142 objects since often (e.g. for customisation functions) the object is passed to a function 145 The ModuleFinder.scan_opcodes_25 implementation this is based was taken from 146 https://hg.python.org/cpython/file/2.7/Lib/modulefinder.py#l364 152 consts = co.co_consts
153 LOAD_CONST = modulefinder.LOAD_CONST
154 IMPORT_NAME = modulefinder.IMPORT_NAME
155 STORE_OPS = modulefinder.STORE_OPS
156 HAVE_ARGUMENT = modulefinder.HAVE_ARGUMENT
157 LOAD_ATTR = chr(dis.opname.index(
'LOAD_ATTR'))
158 LOAD_NAME = chr(dis.opname.index(
'LOAD_NAME'))
159 CALL_FUNCTION = chr(dis.opname.index(
'CALL_FUNCTION'))
160 LOAD_LOAD_AND_IMPORT = LOAD_CONST + LOAD_CONST + IMPORT_NAME
163 indexOfLoadConst = names.index(
"load")
166 loadMethodOpcodes = LOAD_ATTR+struct.pack(
'<H',indexOfLoadConst)
169 loadMethodOpcodes=
None 175 if loadMethodOpcodes!=
None and len(code)>=9 :
176 if code[:3]==loadMethodOpcodes :
181 if code[6]==CALL_FUNCTION :
185 indexInTable=
unpack(
'<H',code[4:6])[0]
186 if code[3]==LOAD_CONST :
188 loadMethodArgument=consts[indexInTable]
193 loadMethodArgument = loadMethodArgument.replace(
"/",
".")
201 for subModule
in loadMethodArgument.split(
".") :
202 moduleInfo=imp.find_module( subModule, parentFilename )
203 parentFilename=[moduleInfo[1]]
205 yield "import", (
None, loadMethodArgument)
209 for subModule
in loadMethodArgument.split(
".") :
210 moduleInfo=imp.find_module( subModule, parentFilename )
211 parentFilename=[moduleInfo[1]]
213 yield "import", (
None, loadMethodArgument)
214 except Exception
as error:
220 elif code[3]==LOAD_NAME :
224 print(
"Unable to determine the value of variable '"+names[indexInTable]+
"' to see if it is a proces.load(...) statement in file "+co.co_filename)
230 oparg, =
unpack(
'<H', code[1:3])
231 yield "store", (names[oparg],)
234 if code[:9:3] == LOAD_LOAD_AND_IMPORT:
235 oparg_1, oparg_2, oparg_3 =
unpack(
'<xHxHxH', code[:9])
236 level = consts[oparg_1]
238 yield "import", (consts[oparg_2], names[oparg_3])
240 yield "absolute_import", (consts[oparg_2], names[oparg_3])
242 yield "relative_import", (level, consts[oparg_2], names[oparg_3])
245 if c >= HAVE_ARGUMENT:
251 if currentStack
is None : currentStack=[]
253 duplicateIndex=currentStack.index( node )
255 print(
"Removing recursive loop in:")
256 for index
in range(duplicateIndex,len(currentStack)) :
257 print(
" ",currentStack[index].name,
"-->")
259 currentStack[-1].dependencies.remove(node)
262 currentStack.append( node )
263 for subnode
in node.dependencies :
269 packageDict[toplevel] =
Package(toplevel, top =
True)
272 for key, value
in six.iteritems(depgraph):
273 if key.count(
".") == 2
and key != toplevel:
274 packageDict[key] =
Package(key)
275 for name
in value.keys():
276 if name.count(
".") == 2: packageDict[name] =
Package(name)
278 for key, value
in six.iteritems(depgraph):
279 if key.count(
".") == 2
or key == toplevel:
280 package = packageDict[key]
281 package.dependencies = [packageDict[name]
for name
in value.keys()
if name.count(
".") == 2]
285 return packageDict[toplevel]
289 modulefinder =
mymf(path)
290 modulefinder.run_script(filename)
291 globalDependencyDict = modulefinder._depgraph
292 globalDependencyDict[toplevelname] = globalDependencyDict[
"__main__"]
293 return globalDependencyDict
303 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