You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
Fix Python 3.7+ "import as" but keep "import from" working
This commit is contained in:
Binary file not shown.
BIN
test/bytecode_3.5_run/04_importlist.pyc
Normal file
BIN
test/bytecode_3.5_run/04_importlist.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_3.6_run/04_importlist.pyc
Normal file
BIN
test/bytecode_3.6_run/04_importlist.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_3.7_run/04_importlist.pyc
Normal file
BIN
test/bytecode_3.7_run/04_importlist.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.8_run/04_importlist.pyc
Normal file
BIN
test/bytecode_3.8_run/04_importlist.pyc
Normal file
Binary file not shown.
@@ -1,7 +1,14 @@
|
||||
# From 3.7 test_cmath.py
|
||||
# Had bug in 3.x in not having semantic importlist rule
|
||||
def main(osp, Mfile, mainpyfile, dbg=None):
|
||||
try:
|
||||
from xdis import load_module, PYTHON_VERSION, IS_PYPY
|
||||
return PYTHON_VERSION, IS_PYPY, load_module
|
||||
except:
|
||||
pass
|
||||
# bug is treating "import as" as "from xx import" while
|
||||
# still being able to hand "from xx import" properly
|
||||
|
||||
# RUNNABLE!
|
||||
import os.path as osp
|
||||
from sys import path
|
||||
from os import sep, name
|
||||
|
||||
assert osp.basename("a")
|
||||
assert path
|
||||
assert sep
|
||||
assert name
|
||||
|
@@ -598,6 +598,9 @@ class Python37Parser(Python37BaseParser):
|
||||
|
||||
# Where does the POP_TOP really belong?
|
||||
import37 ::= import POP_TOP
|
||||
alias ::= IMPORT_NAME_ATTR IMPORT_FROM store
|
||||
alias ::= IMPORT_NAME_ATTR attributes store
|
||||
import_from ::= LOAD_CONST LOAD_CONST IMPORT_NAME_ATTR importlist POP_TOP
|
||||
|
||||
async_for_stmt ::= setup_loop expr
|
||||
GET_AITER
|
||||
|
@@ -358,6 +358,10 @@ class Scanner37Base(Scanner):
|
||||
# other parts like n_LOAD_CONST in pysource.py for example.
|
||||
pattr = const
|
||||
pass
|
||||
elif opname == "IMPORT_NAME":
|
||||
if "." in inst.argval:
|
||||
opname = "IMPORT_NAME_ATTR"
|
||||
pass
|
||||
elif opname in ("MAKE_FUNCTION", "MAKE_CLOSURE"):
|
||||
flags = argval
|
||||
opname = "MAKE_FUNCTION_%d" % (flags)
|
||||
@@ -888,6 +892,7 @@ class Scanner37Base(Scanner):
|
||||
elif op in self.setup_opts_no_loop:
|
||||
count_SETUP_ += 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from uncompyle6 import PYTHON_VERSION
|
||||
|
||||
|
@@ -73,3 +73,18 @@ def customize_for_version37(self, version):
|
||||
'testfalse_not_and': ( "not (%c)", 0 ),
|
||||
|
||||
})
|
||||
|
||||
def n_import_from(node):
|
||||
relative_path_index = 0
|
||||
if node[relative_path_index].pattr > 0:
|
||||
node[2].pattr = ("." * node[relative_path_index].pattr) + node[2].pattr
|
||||
if isinstance(node[1].pattr, tuple):
|
||||
imports = node[1].pattr
|
||||
for pattr in imports:
|
||||
node[1].pattr = pattr
|
||||
self.default(node)
|
||||
return
|
||||
self.default(node)
|
||||
|
||||
self.n_import_from = n_import_from
|
||||
self.n_import_from_star = n_import_from
|
||||
|
@@ -43,9 +43,6 @@ def make_function2(self, node, is_lambda, nested=1, code_node=None):
|
||||
This code is specialied for Python 2.
|
||||
"""
|
||||
|
||||
# FIXME: call make_function3 if we are self.version >= 3.0
|
||||
# and then simplify the below.
|
||||
|
||||
def build_param(ast, name, default):
|
||||
"""build parameters:
|
||||
- handle defaults
|
||||
|
Reference in New Issue
Block a user