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: