diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2016-05-08 20:44:54 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2016-05-08 20:44:54 (GMT) |
commit | 3e99fdeed5cff4eda913ea0082cdb94e59ce629d (patch) | |
tree | 6967ad7b7a9ce67e532dccaf65bb4bb107308e93 /Lib/modulefinder.py | |
parent | ce41287e996351735ec1564bc1d701dd9057bdcf (diff) | |
parent | 02d9f5e5b2ee2662cb6776ebdafa2f3169452e41 (diff) | |
download | cpython-3e99fdeed5cff4eda913ea0082cdb94e59ce629d.zip cpython-3e99fdeed5cff4eda913ea0082cdb94e59ce629d.tar.gz cpython-3e99fdeed5cff4eda913ea0082cdb94e59ce629d.tar.bz2 |
Issue #26881: The modulefinder module now supports extended opcode arguments.
Diffstat (limited to 'Lib/modulefinder.py')
-rw-r--r-- | Lib/modulefinder.py | 43 |
1 files changed, 17 insertions, 26 deletions
diff --git a/Lib/modulefinder.py b/Lib/modulefinder.py index d8d645c..e220315 100644 --- a/Lib/modulefinder.py +++ b/Lib/modulefinder.py @@ -13,13 +13,12 @@ with warnings.catch_warnings(): warnings.simplefilter('ignore', DeprecationWarning) import imp -# XXX Clean up once str8's cstor matches bytes. -LOAD_CONST = bytes([dis.opmap['LOAD_CONST']]) -IMPORT_NAME = bytes([dis.opmap['IMPORT_NAME']]) -STORE_NAME = bytes([dis.opmap['STORE_NAME']]) -STORE_GLOBAL = bytes([dis.opmap['STORE_GLOBAL']]) +LOAD_CONST = dis.opmap['LOAD_CONST'] +IMPORT_NAME = dis.opmap['IMPORT_NAME'] +STORE_NAME = dis.opmap['STORE_NAME'] +STORE_GLOBAL = dis.opmap['STORE_GLOBAL'] STORE_OPS = STORE_NAME, STORE_GLOBAL -HAVE_ARGUMENT = bytes([dis.HAVE_ARGUMENT]) +EXTENDED_ARG = dis.EXTENDED_ARG # Modulefinder does a good job at simulating Python's, but it can not # handle __path__ modifications packages make at runtime. Therefore there @@ -337,38 +336,30 @@ class ModuleFinder: fullname = name + "." + sub self._add_badmodule(fullname, caller) - def scan_opcodes_25(self, co, - unpack = struct.unpack): + def scan_opcodes(self, co): # Scan the code, and yield 'interesting' opcode combinations - # Python 2.5 version (has absolute and relative imports) code = co.co_code names = co.co_names consts = co.co_consts - LOAD_LOAD_AND_IMPORT = LOAD_CONST + LOAD_CONST + IMPORT_NAME - while code: - c = bytes([code[0]]) - if c in STORE_OPS: - oparg, = unpack('<H', code[1:3]) + opargs = [(op, arg) for _, op, arg in dis._unpack_opargs(code) + if op != EXTENDED_ARG] + for i, (op, oparg) in enumerate(opargs): + if op in STORE_OPS: yield "store", (names[oparg],) - code = code[3:] continue - if code[:9:3] == LOAD_LOAD_AND_IMPORT: - oparg_1, oparg_2, oparg_3 = unpack('<xHxHxH', code[:9]) - level = consts[oparg_1] + if (op == IMPORT_NAME and i >= 2 + and opargs[i-1][0] == opargs[i-2][0] == LOAD_CONST): + level = consts[opargs[i-2][1]] + fromlist = consts[opargs[i-1][1]] if level == 0: # absolute import - yield "absolute_import", (consts[oparg_2], names[oparg_3]) + yield "absolute_import", (fromlist, names[oparg]) else: # relative import - yield "relative_import", (level, consts[oparg_2], names[oparg_3]) - code = code[9:] + yield "relative_import", (level, fromlist, names[oparg]) continue - if c >= HAVE_ARGUMENT: - code = code[3:] - else: - code = code[1:] def scan_code(self, co, m): code = co.co_code - scanner = self.scan_opcodes_25 + scanner = self.scan_opcodes for what, args in scanner(co): if what == "store": name, = args |