diff --git a/uncompyle6/parsers/parse2.py b/uncompyle6/parsers/parse2.py index 2b0d0191..d7f3b2dd 100644 --- a/uncompyle6/parsers/parse2.py +++ b/uncompyle6/parsers/parse2.py @@ -279,8 +279,13 @@ class Python2Parser(PythonParser): self.add_unique_rule("expr1024 ::=%s" % (' expr32' * 32), opname_base, v, customize) self.seen1024 = True - rule = ('list ::= ' + 'expr1024 '*thousands + + collection = opname_base[opname_base.find('_')+1:].lower() + rule = (('%s ::= ' % collection) + 'expr1024 '*thousands + 'expr32 '*thirty32s + 'expr '*(v % 32) + opname) + self.add_unique_rules([ + "expr ::= %s" % collection, + rule], customize) + continue elif opname_base == 'BUILD_MAP': if opname == 'BUILD_MAP_n': # PyPy sometimes has no count. Sigh. diff --git a/uncompyle6/parsers/parse3.py b/uncompyle6/parsers/parse3.py index b0223fae..f3415bf9 100644 --- a/uncompyle6/parsers/parse3.py +++ b/uncompyle6/parsers/parse3.py @@ -678,10 +678,13 @@ class Python3Parser(PythonParser): rule = ('load_closure ::= %s%s' % (('LOAD_CLOSURE ' * v), opname)) self.add_unique_rule(rule, opname, token.attr, customize) if not is_LOAD_CLOSURE or v == 0: - rule = ('list ::= ' + 'expr1024 ' * int(v//1024) + + collection = opname_base[opname_base.find('_')+1:].lower() + rule = (('%s ::= ' % collection) + 'expr1024 ' * int(v//1024) + 'expr32 ' * int((v//32) % 32) + 'expr ' * (v % 32) + opname) - self.add_unique_rule(rule, opname, token.attr, customize) + self.add_unique_rules([ + 'expr ::= %s' % collection, + rule], customize) continue elif opname_base == 'BUILD_SLICE': if token.attr == 2: diff --git a/uncompyle6/semantics/fragments.py b/uncompyle6/semantics/fragments.py index cf1a0de5..bdd39ec4 100644 --- a/uncompyle6/semantics/fragments.py +++ b/uncompyle6/semantics/fragments.py @@ -364,7 +364,12 @@ class FragmentsWalker(pysource.SourceWalker, object): def n_LOAD_CONST(self, node): start = len(self.f.getvalue()) data = node.pattr; datatype = type(data) - if isinstance(datatype, int) and data == minint: + if isinstance(data, float) and str(data) in frozenset(['nan', '-nan', 'inf', '-inf']): + # float values 'nan' and 'inf' are not directly representable in Python at least + # before 3.5 and even there it is via a library constant. + # So we will canonicalize their representation as float('nan') and float('inf') + self.write("float('%s')" % data) + elif isinstance(datatype, int) and data == minint: # convert to hex, since decimal representation # would result in 'LOAD_CONST; UNARY_NEGATIVE' # change:hG/2002-02-07: this was done for all negative integers @@ -1457,6 +1462,9 @@ class FragmentsWalker(pysource.SourceWalker, object): self.indent_less(INDENT_PER_LEVEL) self.prec = p self.prune() + return + + n_set = n_tuple = n_build_set = n_list def template_engine(self, entry, startnode): """The format template interpetation engine. See the comment at the diff --git a/uncompyle6/semantics/make_function.py b/uncompyle6/semantics/make_function.py index aee58bce..8a1d1f4a 100644 --- a/uncompyle6/semantics/make_function.py +++ b/uncompyle6/semantics/make_function.py @@ -500,7 +500,7 @@ def make_function3(self, node, is_lambda, nested=1, codeNode=None): if (expr_node[0] == 'LOAD_CONST' and isinstance(expr_node[0].attr, tuple)): defparams = list(expr_node[0].attr) - elif expr_node[0] == 'list': + elif expr_node[0] in frozenset(('list', 'tuple', 'dict', 'set')): defparams = [self.traverse(n, indent='') for n in expr_node[0][:-1]] else: defparams = [] diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index 488bf2c8..9ff485e5 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -1883,7 +1883,7 @@ class SourceWalker(GenericASTTraversal, object): self.prune() return - n_build_set = n_list + n_set = n_tuple = n_build_set = n_list def n_unpack(self, node): if node[0].kind.startswith('UNPACK_EX'):