You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 01:09:52 +08:00
Merge branch 'python-3.0-to-3.2' into python-2.4-to-2.7
This commit is contained in:
@@ -5,4 +5,4 @@ if [[ $0 == ${BASH_SOURCE[0]} ]] ; then
|
|||||||
echo "This script should be *sourced* rather than run directly through bash"
|
echo "This script should be *sourced* rather than run directly through bash"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
export PYVERSIONS='3.6.15 pypy3.6-7.3.1 3.7.16 pypy3.7-7.3.9 pypy3.8-7.3.10 pyston-2.3.5 3.8.17'
|
export PYVERSIONS='3.6.15 pypy3.6-7.3.1 3.7.16 pypy3.7-7.3.9 pypy3.8-7.3.10 pyston-2.3.5 3.8.18'
|
||||||
|
@@ -18,12 +18,7 @@ function checkout_version {
|
|||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
# FIXME put some of the below in a common routine
|
|
||||||
function finish {
|
|
||||||
cd $owd
|
|
||||||
}
|
|
||||||
owd=$(pwd)
|
owd=$(pwd)
|
||||||
trap finish EXIT
|
|
||||||
|
|
||||||
export PATH=$HOME/.pyenv/bin/pyenv:$PATH
|
export PATH=$HOME/.pyenv/bin/pyenv:$PATH
|
||||||
|
|
||||||
@@ -35,4 +30,4 @@ cd $fulldir/..
|
|||||||
|
|
||||||
git pull
|
git pull
|
||||||
rm -v */.python-version || true
|
rm -v */.python-version || true
|
||||||
finish
|
cd $owd
|
||||||
|
@@ -19,11 +19,7 @@ function checkout_version {
|
|||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
function finish {
|
|
||||||
cd $owd
|
|
||||||
}
|
|
||||||
owd=$(pwd)
|
owd=$(pwd)
|
||||||
trap finish EXIT
|
|
||||||
|
|
||||||
export PATH=$HOME/.pyenv/bin/pyenv:$PATH
|
export PATH=$HOME/.pyenv/bin/pyenv:$PATH
|
||||||
|
|
||||||
@@ -34,4 +30,4 @@ fulldir=$(readlink -f $mydir)
|
|||||||
|
|
||||||
git pull
|
git pull
|
||||||
rm -v */.python-version || true
|
rm -v */.python-version || true
|
||||||
finish
|
cd $owd
|
||||||
|
@@ -20,9 +20,6 @@ function checkout_version {
|
|||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
function finish {
|
|
||||||
cd $owd
|
|
||||||
}
|
|
||||||
owd=$(pwd)
|
owd=$(pwd)
|
||||||
trap finish EXIT
|
trap finish EXIT
|
||||||
|
|
||||||
@@ -36,4 +33,4 @@ cd $fulldir/..
|
|||||||
|
|
||||||
git pull
|
git pull
|
||||||
rm -v */.python-version || true
|
rm -v */.python-version || true
|
||||||
finish
|
cd $owd
|
||||||
|
@@ -19,11 +19,7 @@ function checkout_version {
|
|||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
function finish {
|
|
||||||
cd $owd
|
|
||||||
}
|
|
||||||
owd=$(pwd)
|
owd=$(pwd)
|
||||||
trap finish EXIT
|
|
||||||
|
|
||||||
export PATH=$HOME/.pyenv/bin/pyenv:$PATH
|
export PATH=$HOME/.pyenv/bin/pyenv:$PATH
|
||||||
|
|
||||||
@@ -36,4 +32,4 @@ rm -v */.python-version || true
|
|||||||
|
|
||||||
git pull
|
git pull
|
||||||
rm -v */.python-version || true
|
rm -v */.python-version || true
|
||||||
finish
|
cd $owd
|
||||||
|
@@ -601,27 +601,6 @@ class Scanner:
|
|||||||
return self.Token
|
return self.Token
|
||||||
|
|
||||||
|
|
||||||
# TODO: after the next xdis release, use from there instead.
|
|
||||||
def parse_fn_counts_30_35(argc):
|
|
||||||
"""
|
|
||||||
In Python 3.0 to 3.5 MAKE_CLOSURE and MAKE_FUNCTION encode
|
|
||||||
arguments counts of positional, default + named, and annotation
|
|
||||||
arguments a particular kind of encoding where each of
|
|
||||||
the entry a a packed byted value of the lower 24 bits
|
|
||||||
of ``argc``. The high bits of argc may have come from
|
|
||||||
an EXTENDED_ARG instruction. Here, we unpack the values
|
|
||||||
from the ``argc`` int and return a triple of the
|
|
||||||
positional args, named_args, and annotation args.
|
|
||||||
"""
|
|
||||||
annotate_count = (argc >> 16) & 0x7FFF
|
|
||||||
# For some reason that I don't understand, annotate_args is off by one
|
|
||||||
# when there is an EXENDED_ARG instruction from what is documented in
|
|
||||||
# https://docs.python.org/3.4/library/dis.html#opcode-MAKE_CLOSURE
|
|
||||||
if annotate_count > 1:
|
|
||||||
annotate_count -= 1
|
|
||||||
return ((argc & 0xFF), (argc >> 8) & 0xFF, annotate_count)
|
|
||||||
|
|
||||||
|
|
||||||
def get_scanner(version, is_pypy=False, show_asm=None):
|
def get_scanner(version, is_pypy=False, show_asm=None):
|
||||||
# If version is a string, turn that into the corresponding float.
|
# If version is a string, turn that into the corresponding float.
|
||||||
if isinstance(version, str):
|
if isinstance(version, str):
|
||||||
@@ -666,6 +645,16 @@ def get_scanner(version, is_pypy=False, show_asm=None):
|
|||||||
return scanner
|
return scanner
|
||||||
|
|
||||||
|
|
||||||
|
def prefer_double_quote(string: str) -> str:
|
||||||
|
"""
|
||||||
|
Prefer a double quoted string over a
|
||||||
|
single quoted string when possible
|
||||||
|
"""
|
||||||
|
if string.find("'") == -1:
|
||||||
|
return '"%s"' % string
|
||||||
|
return repr(string)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import inspect
|
import inspect
|
||||||
|
|
||||||
|
@@ -39,8 +39,9 @@ import xdis
|
|||||||
import xdis.opcodes.opcode_33 as op3
|
import xdis.opcodes.opcode_33 as op3
|
||||||
from xdis import Instruction, instruction_size, iscode
|
from xdis import Instruction, instruction_size, iscode
|
||||||
from xdis.bytecode import _get_const_info
|
from xdis.bytecode import _get_const_info
|
||||||
|
from xdis.opcodes.opcode_3x import parse_fn_counts_30_35
|
||||||
|
|
||||||
from uncompyle6.scanner import CONST_COLLECTIONS, Scanner, parse_fn_counts_30_35
|
from uncompyle6.scanner import CONST_COLLECTIONS, Scanner, prefer_double_quote
|
||||||
from uncompyle6.scanners.tok import Token
|
from uncompyle6.scanners.tok import Token
|
||||||
from uncompyle6.util import get_code_name
|
from uncompyle6.util import get_code_name
|
||||||
|
|
||||||
@@ -596,6 +597,7 @@ class Scanner3(Scanner):
|
|||||||
pattr = "<code_object " + const.co_name + ">"
|
pattr = "<code_object " + const.co_name + ">"
|
||||||
elif isinstance(const, str) or isinstance(const, unicode):
|
elif isinstance(const, str) or isinstance(const, unicode):
|
||||||
opname = "LOAD_STR"
|
opname = "LOAD_STR"
|
||||||
|
pattr = prefer_double_quote(inst.argval)
|
||||||
else:
|
else:
|
||||||
if isinstance(inst.arg, int) and inst.arg < len(co.co_consts):
|
if isinstance(inst.arg, int) and inst.arg < len(co.co_consts):
|
||||||
argval, _ = _get_const_info(inst.arg, co.co_consts)
|
argval, _ = _get_const_info(inst.arg, co.co_consts)
|
||||||
|
@@ -38,7 +38,7 @@ import xdis.opcodes.opcode_37 as op3
|
|||||||
from xdis import Instruction, instruction_size, iscode
|
from xdis import Instruction, instruction_size, iscode
|
||||||
from xdis.bytecode import _get_const_info
|
from xdis.bytecode import _get_const_info
|
||||||
|
|
||||||
from uncompyle6.scanner import Scanner, Token
|
from uncompyle6.scanner import Scanner, Token, prefer_double_quote
|
||||||
|
|
||||||
globals().update(op3.opmap)
|
globals().update(op3.opmap)
|
||||||
|
|
||||||
@@ -383,6 +383,7 @@ class Scanner37Base(Scanner):
|
|||||||
pattr = "<code_object " + const.co_name + ">"
|
pattr = "<code_object " + const.co_name + ">"
|
||||||
elif isinstance(const, str):
|
elif isinstance(const, str):
|
||||||
opname = "LOAD_STR"
|
opname = "LOAD_STR"
|
||||||
|
pattr = prefer_double_quote(inst.argval)
|
||||||
else:
|
else:
|
||||||
if isinstance(inst.arg, int) and inst.arg < len(co.co_consts):
|
if isinstance(inst.arg, int) and inst.arg < len(co.co_consts):
|
||||||
argval, _ = _get_const_info(inst.arg, co.co_consts)
|
argval, _ = _get_const_info(inst.arg, co.co_consts)
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2017-2023 by Rocky Bernstein
|
# Copyright (c) 2017-2024 by Rocky Bernstein
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,9 +14,11 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
"""Constants and initial table values used in pysource.py and fragments.py"""
|
"""Constants and initial table values used in pysource.py and fragments.py"""
|
||||||
|
|
||||||
import re, sys
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
from uncompyle6.parsers.treenode import SyntaxTree
|
from uncompyle6.parsers.treenode import SyntaxTree
|
||||||
from uncompyle6.scanners.tok import Token, NoneToken
|
from uncompyle6.scanners.tok import NoneToken, Token
|
||||||
|
|
||||||
minint = -sys.maxint - 1
|
minint = -sys.maxint - 1
|
||||||
maxint = sys.maxint
|
maxint = sys.maxint
|
||||||
@@ -45,6 +47,7 @@ maxint = sys.maxint
|
|||||||
# call((.. op ..)).
|
# call((.. op ..)).
|
||||||
|
|
||||||
NO_PARENTHESIS_EVER = 100
|
NO_PARENTHESIS_EVER = 100
|
||||||
|
PARENTHESIS_ALWAYS = -2
|
||||||
|
|
||||||
# fmt: off
|
# fmt: off
|
||||||
PRECEDENCE = {
|
PRECEDENCE = {
|
||||||
|
@@ -18,7 +18,14 @@ Custom Nonterminal action functions. See NonterminalActions docstring.
|
|||||||
|
|
||||||
from uncompyle6.parsers.treenode import SyntaxTree
|
from uncompyle6.parsers.treenode import SyntaxTree
|
||||||
from uncompyle6.scanners.tok import Token
|
from uncompyle6.scanners.tok import Token
|
||||||
from uncompyle6.semantics.consts import INDENT_PER_LEVEL, NONE, PRECEDENCE, minint
|
from uncompyle6.semantics.consts import (
|
||||||
|
INDENT_PER_LEVEL,
|
||||||
|
NO_PARENTHESIS_EVER,
|
||||||
|
NONE,
|
||||||
|
PARENTHESIS_ALWAYS,
|
||||||
|
PRECEDENCE,
|
||||||
|
minint,
|
||||||
|
)
|
||||||
from uncompyle6.semantics.helper import find_code_node, flatten_list
|
from uncompyle6.semantics.helper import find_code_node, flatten_list
|
||||||
from uncompyle6.util import better_repr
|
from uncompyle6.util import better_repr
|
||||||
|
|
||||||
@@ -39,8 +46,9 @@ class NonterminalActions:
|
|||||||
# parenthesis surrounding it. A high value indicates no
|
# parenthesis surrounding it. A high value indicates no
|
||||||
# parenthesis are needed.
|
# parenthesis are needed.
|
||||||
self.prec = 1000
|
self.prec = 1000
|
||||||
|
self.in_format_string = False
|
||||||
|
|
||||||
def n_alias(self, node):
|
def n_alias(self, node: SyntaxTree):
|
||||||
if self.version <= (2, 1):
|
if self.version <= (2, 1):
|
||||||
if len(node) == 2:
|
if len(node) == 2:
|
||||||
store = node[1]
|
store = node[1]
|
||||||
@@ -65,7 +73,7 @@ class NonterminalActions:
|
|||||||
|
|
||||||
n_alias37 = n_alias
|
n_alias37 = n_alias
|
||||||
|
|
||||||
def n_assign(self, node):
|
def n_assign(self, node: SyntaxTree):
|
||||||
# A horrible hack for Python 3.0 .. 3.2
|
# A horrible hack for Python 3.0 .. 3.2
|
||||||
if (3, 0) <= self.version <= (3, 2) and len(node) == 2:
|
if (3, 0) <= self.version <= (3, 2) and len(node) == 2:
|
||||||
if (
|
if (
|
||||||
@@ -76,19 +84,19 @@ class NonterminalActions:
|
|||||||
self.prune()
|
self.prune()
|
||||||
self.default(node)
|
self.default(node)
|
||||||
|
|
||||||
def n_assign2(self, node):
|
def n_assign2(self, node: SyntaxTree):
|
||||||
for n in node[-2:]:
|
for n in node[-2:]:
|
||||||
if n[0] == "unpack":
|
if n[0] == "unpack":
|
||||||
n[0].kind = "unpack_w_parens"
|
n[0].kind = "unpack_w_parens"
|
||||||
self.default(node)
|
self.default(node)
|
||||||
|
|
||||||
def n_assign3(self, node):
|
def n_assign3(self, node: SyntaxTree):
|
||||||
for n in node[-3:]:
|
for n in node[-3:]:
|
||||||
if n[0] == "unpack":
|
if n[0] == "unpack":
|
||||||
n[0].kind = "unpack_w_parens"
|
n[0].kind = "unpack_w_parens"
|
||||||
self.default(node)
|
self.default(node)
|
||||||
|
|
||||||
def n_attribute(self, node):
|
def n_attribute(self, node: SyntaxTree):
|
||||||
if node[0] == "LOAD_CONST" or node[0] == "expr" and node[0][0] == "LOAD_CONST":
|
if node[0] == "LOAD_CONST" or node[0] == "expr" and node[0][0] == "LOAD_CONST":
|
||||||
# FIXME: I didn't record which constants parenthesis is
|
# FIXME: I didn't record which constants parenthesis is
|
||||||
# necessary. However, I suspect that we could further
|
# necessary. However, I suspect that we could further
|
||||||
@@ -98,7 +106,7 @@ class NonterminalActions:
|
|||||||
node.kind = "attribute_w_parens"
|
node.kind = "attribute_w_parens"
|
||||||
self.default(node)
|
self.default(node)
|
||||||
|
|
||||||
def n_bin_op(self, node):
|
def n_bin_op(self, node: SyntaxTree):
|
||||||
"""bin_op (formerly "binary_expr") is the Python AST BinOp"""
|
"""bin_op (formerly "binary_expr") is the Python AST BinOp"""
|
||||||
self.preorder(node[0])
|
self.preorder(node[0])
|
||||||
self.write(" ")
|
self.write(" ")
|
||||||
@@ -110,9 +118,9 @@ class NonterminalActions:
|
|||||||
self.prec += 1
|
self.prec += 1
|
||||||
self.prune()
|
self.prune()
|
||||||
|
|
||||||
def n_build_slice2(self, node):
|
def n_build_slice2(self, node: SyntaxTree):
|
||||||
p = self.prec
|
p = self.prec
|
||||||
self.prec = 100
|
self.prec = NO_PARENTHESIS_EVER
|
||||||
if not node[0].isNone():
|
if not node[0].isNone():
|
||||||
self.preorder(node[0])
|
self.preorder(node[0])
|
||||||
self.write(":")
|
self.write(":")
|
||||||
@@ -121,9 +129,9 @@ class NonterminalActions:
|
|||||||
self.prec = p
|
self.prec = p
|
||||||
self.prune() # stop recursing
|
self.prune() # stop recursing
|
||||||
|
|
||||||
def n_build_slice3(self, node):
|
def n_build_slice3(self, node: SyntaxTree):
|
||||||
p = self.prec
|
p = self.prec
|
||||||
self.prec = 100
|
self.prec = NO_PARENTHESIS_EVER
|
||||||
if not node[0].isNone():
|
if not node[0].isNone():
|
||||||
self.preorder(node[0])
|
self.preorder(node[0])
|
||||||
self.write(":")
|
self.write(":")
|
||||||
@@ -135,7 +143,7 @@ class NonterminalActions:
|
|||||||
self.prec = p
|
self.prec = p
|
||||||
self.prune() # stop recursing
|
self.prune() # stop recursing
|
||||||
|
|
||||||
def n_classdef(self, node):
|
def n_classdef(self, node: SyntaxTree):
|
||||||
if self.version >= (3, 6):
|
if self.version >= (3, 6):
|
||||||
self.n_classdef36(node)
|
self.n_classdef36(node)
|
||||||
elif self.version >= (3, 0):
|
elif self.version >= (3, 0):
|
||||||
@@ -198,7 +206,7 @@ class NonterminalActions:
|
|||||||
|
|
||||||
n_classdefdeco2 = n_classdef
|
n_classdefdeco2 = n_classdef
|
||||||
|
|
||||||
def n_const_list(self, node):
|
def n_const_list(self, node: SyntaxTree):
|
||||||
"""
|
"""
|
||||||
prettyprint a constant dict, list, set or tuple.
|
prettyprint a constant dict, list, set or tuple.
|
||||||
"""
|
"""
|
||||||
@@ -292,7 +300,7 @@ class NonterminalActions:
|
|||||||
self.prune()
|
self.prune()
|
||||||
return
|
return
|
||||||
|
|
||||||
def n_delete_subscript(self, node):
|
def n_delete_subscript(self, node: SyntaxTree):
|
||||||
if node[-2][0] == "build_list" and node[-2][0][-1].kind.startswith(
|
if node[-2][0] == "build_list" and node[-2][0][-1].kind.startswith(
|
||||||
"BUILD_TUPLE"
|
"BUILD_TUPLE"
|
||||||
):
|
):
|
||||||
@@ -302,7 +310,7 @@ class NonterminalActions:
|
|||||||
|
|
||||||
n_store_subscript = n_subscript = n_delete_subscript
|
n_store_subscript = n_subscript = n_delete_subscript
|
||||||
|
|
||||||
def n_dict(self, node):
|
def n_dict(self, node: SyntaxTree):
|
||||||
"""
|
"""
|
||||||
Prettyprint a dict.
|
Prettyprint a dict.
|
||||||
'dict' is something like k = {'a': 1, 'b': 42}"
|
'dict' is something like k = {'a': 1, 'b': 42}"
|
||||||
@@ -314,7 +322,7 @@ class NonterminalActions:
|
|||||||
return
|
return
|
||||||
|
|
||||||
p = self.prec
|
p = self.prec
|
||||||
self.prec = 100
|
self.prec = PRECEDENCE["dict"]
|
||||||
|
|
||||||
self.indent_more(INDENT_PER_LEVEL)
|
self.indent_more(INDENT_PER_LEVEL)
|
||||||
sep = INDENT_PER_LEVEL[:-1]
|
sep = INDENT_PER_LEVEL[:-1]
|
||||||
@@ -326,8 +334,8 @@ class NonterminalActions:
|
|||||||
if node[0].kind.startswith("kvlist"):
|
if node[0].kind.startswith("kvlist"):
|
||||||
# Python 3.5+ style key/value list in dict
|
# Python 3.5+ style key/value list in dict
|
||||||
kv_node = node[0]
|
kv_node = node[0]
|
||||||
l = list(kv_node)
|
ll = list(kv_node)
|
||||||
length = len(l)
|
length = len(ll)
|
||||||
if kv_node[-1].kind.startswith("BUILD_MAP"):
|
if kv_node[-1].kind.startswith("BUILD_MAP"):
|
||||||
length -= 1
|
length -= 1
|
||||||
i = 0
|
i = 0
|
||||||
@@ -335,7 +343,7 @@ class NonterminalActions:
|
|||||||
# Respect line breaks from source
|
# Respect line breaks from source
|
||||||
while i < length:
|
while i < length:
|
||||||
self.write(sep)
|
self.write(sep)
|
||||||
name = self.traverse(l[i], indent="")
|
name = self.traverse(ll[i], indent="")
|
||||||
if i > 0:
|
if i > 0:
|
||||||
line_number = self.indent_if_source_nl(
|
line_number = self.indent_if_source_nl(
|
||||||
line_number, self.indent + INDENT_PER_LEVEL[:-1]
|
line_number, self.indent + INDENT_PER_LEVEL[:-1]
|
||||||
@@ -343,7 +351,7 @@ class NonterminalActions:
|
|||||||
line_number = self.line_number
|
line_number = self.line_number
|
||||||
self.write(name, ": ")
|
self.write(name, ": ")
|
||||||
value = self.traverse(
|
value = self.traverse(
|
||||||
l[i + 1], indent=self.indent + (len(name) + 2) * " "
|
ll[i + 1], indent=self.indent + (len(name) + 2) * " "
|
||||||
)
|
)
|
||||||
self.write(value)
|
self.write(value)
|
||||||
sep = ", "
|
sep = ", "
|
||||||
@@ -356,15 +364,15 @@ class NonterminalActions:
|
|||||||
elif len(node) > 1 and node[1].kind.startswith("kvlist"):
|
elif len(node) > 1 and node[1].kind.startswith("kvlist"):
|
||||||
# Python 3.0..3.4 style key/value list in dict
|
# Python 3.0..3.4 style key/value list in dict
|
||||||
kv_node = node[1]
|
kv_node = node[1]
|
||||||
l = list(kv_node)
|
ll = list(kv_node)
|
||||||
if len(l) > 0 and l[0].kind == "kv3":
|
if len(ll) > 0 and ll[0].kind == "kv3":
|
||||||
# Python 3.2 does this
|
# Python 3.2 does this
|
||||||
kv_node = node[1][0]
|
kv_node = node[1][0]
|
||||||
l = list(kv_node)
|
ll = list(kv_node)
|
||||||
i = 0
|
i = 0
|
||||||
while i < len(l):
|
while i < len(ll):
|
||||||
self.write(sep)
|
self.write(sep)
|
||||||
name = self.traverse(l[i + 1], indent="")
|
name = self.traverse(ll[i + 1], indent="")
|
||||||
if i > 0:
|
if i > 0:
|
||||||
line_number = self.indent_if_source_nl(
|
line_number = self.indent_if_source_nl(
|
||||||
line_number, self.indent + INDENT_PER_LEVEL[:-1]
|
line_number, self.indent + INDENT_PER_LEVEL[:-1]
|
||||||
@@ -373,7 +381,7 @@ class NonterminalActions:
|
|||||||
line_number = self.line_number
|
line_number = self.line_number
|
||||||
self.write(name, ": ")
|
self.write(name, ": ")
|
||||||
value = self.traverse(
|
value = self.traverse(
|
||||||
l[i], indent=self.indent + (len(name) + 2) * " "
|
ll[i], indent=self.indent + (len(name) + 2) * " "
|
||||||
)
|
)
|
||||||
self.write(value)
|
self.write(value)
|
||||||
sep = ", "
|
sep = ", "
|
||||||
@@ -591,7 +599,7 @@ class NonterminalActions:
|
|||||||
self.println(lines[-1], quote)
|
self.println(lines[-1], quote)
|
||||||
self.prune()
|
self.prune()
|
||||||
|
|
||||||
def n_elifelsestmtr(self, node):
|
def n_elifelsestmtr(self, node: SyntaxTree):
|
||||||
if node[2] == "COME_FROM":
|
if node[2] == "COME_FROM":
|
||||||
return_stmts_node = node[3]
|
return_stmts_node = node[3]
|
||||||
node.kind = "elifelsestmtr2"
|
node.kind = "elifelsestmtr2"
|
||||||
@@ -622,7 +630,7 @@ class NonterminalActions:
|
|||||||
self.indent_less()
|
self.indent_less()
|
||||||
self.prune()
|
self.prune()
|
||||||
|
|
||||||
def n_except_cond2(self, node):
|
def n_except_cond2(self, node: SyntaxTree):
|
||||||
if node[-1] == "come_from_opt":
|
if node[-1] == "come_from_opt":
|
||||||
unpack_node = -3
|
unpack_node = -3
|
||||||
else:
|
else:
|
||||||
@@ -636,7 +644,7 @@ class NonterminalActions:
|
|||||||
# FIXME: figure out how to get this into customization
|
# FIXME: figure out how to get this into customization
|
||||||
# put so that we can get access via super from
|
# put so that we can get access via super from
|
||||||
# the fragments routine.
|
# the fragments routine.
|
||||||
def n_exec_stmt(self, node):
|
def n_exec_stmt(self, node: SyntaxTree):
|
||||||
"""
|
"""
|
||||||
exec_stmt ::= expr exprlist DUP_TOP EXEC_STMT
|
exec_stmt ::= expr exprlist DUP_TOP EXEC_STMT
|
||||||
exec_stmt ::= expr exprlist EXEC_STMT
|
exec_stmt ::= expr exprlist EXEC_STMT
|
||||||
@@ -668,7 +676,9 @@ class NonterminalActions:
|
|||||||
# hasattr(self, 'current_line_number')):
|
# hasattr(self, 'current_line_number')):
|
||||||
# self.source_linemap[self.current_line_number] = n.linestart
|
# self.source_linemap[self.current_line_number] = n.linestart
|
||||||
|
|
||||||
self.prec = PRECEDENCE.get(n.kind, -2)
|
if n.kind != "expr":
|
||||||
|
self.prec = PRECEDENCE.get(n.kind, PARENTHESIS_ALWAYS)
|
||||||
|
|
||||||
if n == "LOAD_CONST" and repr(n.pattr)[0] == "-":
|
if n == "LOAD_CONST" and repr(n.pattr)[0] == "-":
|
||||||
self.prec = 6
|
self.prec = 6
|
||||||
|
|
||||||
@@ -724,7 +734,7 @@ class NonterminalActions:
|
|||||||
self.write(")")
|
self.write(")")
|
||||||
self.prune()
|
self.prune()
|
||||||
|
|
||||||
n_generator_exp_async = n_generator_exp
|
n_genexpr_func = n_generator_exp_async = n_generator_exp
|
||||||
|
|
||||||
def n_ifelsestmtr(self, node):
|
def n_ifelsestmtr(self, node):
|
||||||
if node[2] == "COME_FROM":
|
if node[2] == "COME_FROM":
|
||||||
@@ -804,7 +814,7 @@ class NonterminalActions:
|
|||||||
self.make_function(node, is_lambda=True, code_node=node[-2])
|
self.make_function(node, is_lambda=True, code_node=node[-2])
|
||||||
self.prune() # stop recursing
|
self.prune() # stop recursing
|
||||||
|
|
||||||
def n_list(self, node):
|
def n_list(self, node: SyntaxTree):
|
||||||
"""
|
"""
|
||||||
prettyprint a dict, list, set or tuple.
|
prettyprint a dict, list, set or tuple.
|
||||||
"""
|
"""
|
||||||
@@ -835,13 +845,16 @@ class NonterminalActions:
|
|||||||
if lastnodetype.startswith("BUILD_LIST"):
|
if lastnodetype.startswith("BUILD_LIST"):
|
||||||
self.write("[")
|
self.write("[")
|
||||||
endchar = "]"
|
endchar = "]"
|
||||||
|
|
||||||
elif lastnodetype.startswith("BUILD_MAP_UNPACK"):
|
elif lastnodetype.startswith("BUILD_MAP_UNPACK"):
|
||||||
self.write("{*")
|
self.write("{*")
|
||||||
endchar = "}"
|
endchar = "}"
|
||||||
|
|
||||||
elif lastnodetype.startswith("BUILD_SET"):
|
elif lastnodetype.startswith("BUILD_SET"):
|
||||||
self.write("{")
|
self.write("{")
|
||||||
endchar = "}"
|
endchar = "}"
|
||||||
elif lastnodetype.startswith("BUILD_TUPLE"):
|
|
||||||
|
elif lastnodetype.startswith("BUILD_TUPLE") or node == "tuple":
|
||||||
# Tuples can appear places that can NOT
|
# Tuples can appear places that can NOT
|
||||||
# have parenthesis around them, like array
|
# have parenthesis around them, like array
|
||||||
# subscripts. We check for that by seeing
|
# subscripts. We check for that by seeing
|
||||||
@@ -862,6 +875,7 @@ class NonterminalActions:
|
|||||||
elif lastnodetype.startswith("ROT_TWO"):
|
elif lastnodetype.startswith("ROT_TWO"):
|
||||||
self.write("(")
|
self.write("(")
|
||||||
endchar = ")"
|
endchar = ")"
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
"Internal Error: n_build_list expects list, tuple, set, or unpack"
|
"Internal Error: n_build_list expects list, tuple, set, or unpack"
|
||||||
@@ -900,7 +914,7 @@ class NonterminalActions:
|
|||||||
self.prune()
|
self.prune()
|
||||||
return
|
return
|
||||||
|
|
||||||
n_set = n_tuple = n_build_set = n_list
|
n_set = n_build_set = n_tuple = n_list
|
||||||
|
|
||||||
def n_list_comp(self, node):
|
def n_list_comp(self, node):
|
||||||
"""List comprehensions"""
|
"""List comprehensions"""
|
||||||
|
Reference in New Issue
Block a user