Issue #2335: Backport set literals syntax from Python 3.x.
diff --git a/Lib/compiler/ast.py b/Lib/compiler/ast.py
index f923077..f47434c 100644
--- a/Lib/compiler/ast.py
+++ b/Lib/compiler/ast.py
@@ -1107,6 +1107,22 @@
def __repr__(self):
return "RightShift((%s, %s))" % (repr(self.left), repr(self.right))
+class Set(Node):
+ def __init__(self, nodes, lineno=None):
+ self.nodes = nodes
+ self.lineno = lineno
+
+ def getChildren(self):
+ return tuple(flatten(self.nodes))
+
+ def getChildNodes(self):
+ nodelist = []
+ nodelist.extend(flatten_nodes(self.nodes))
+ return tuple(nodelist)
+
+ def __repr__(self):
+ return "Set(%s)" % (repr(self.nodes),)
+
class Slice(Node):
def __init__(self, expr, flags, lower, upper, lineno=None):
self.expr = expr
diff --git a/Lib/compiler/pyassem.py b/Lib/compiler/pyassem.py
index be0255d..88510de 100644
--- a/Lib/compiler/pyassem.py
+++ b/Lib/compiler/pyassem.py
@@ -734,6 +734,8 @@
return -count+1
def BUILD_LIST(self, count):
return -count+1
+ def BUILD_SET(self, count):
+ return -count+1
def CALL_FUNCTION(self, argc):
hi, lo = divmod(argc, 256)
return -(lo + hi * 2)
diff --git a/Lib/compiler/pycodegen.py b/Lib/compiler/pycodegen.py
index 960c4fc..bef9c70 100644
--- a/Lib/compiler/pycodegen.py
+++ b/Lib/compiler/pycodegen.py
@@ -1215,6 +1215,12 @@
self.visit(elt)
self.emit('BUILD_LIST', len(node.nodes))
+ def visitSet(self, node):
+ self.set_lineno(node)
+ for elt in node.nodes:
+ self.visit(elt)
+ self.emit('BUILD_SET', len(node.nodes))
+
def visitSliceobj(self, node):
for child in node.nodes:
self.visit(child)
diff --git a/Lib/compiler/transformer.py b/Lib/compiler/transformer.py
index 2a156d3..816f13b 100644
--- a/Lib/compiler/transformer.py
+++ b/Lib/compiler/transformer.py
@@ -749,7 +749,7 @@
def atom_lbrace(self, nodelist):
if nodelist[1][0] == token.RBRACE:
return Dict((), lineno=nodelist[0][2])
- return self.com_dictmaker(nodelist[1])
+ return self.com_dictorsetmaker(nodelist[1])
def atom_backquote(self, nodelist):
return Backquote(self.com_node(nodelist[1]))
@@ -1197,13 +1197,21 @@
assert node[0] == symbol.gen_iter
return node[1]
- def com_dictmaker(self, nodelist):
- # dictmaker: test ':' test (',' test ':' value)* [',']
- items = []
- for i in range(1, len(nodelist), 4):
- items.append((self.com_node(nodelist[i]),
- self.com_node(nodelist[i+2])))
- return Dict(items, lineno=items[0][0].lineno)
+ def com_dictorsetmaker(self, nodelist):
+ # dictorsetmaker: ( (test ':' test (',' test ':' test)* [',']) |
+ # (test (',' test)* [',']) )
+ assert nodelist[0] == symbol.dictorsetmaker
+ if len(nodelist) == 2 or nodelist[2][0] == token.COMMA:
+ items = []
+ for i in range(1, len(nodelist), 2):
+ items.append(self.com_node(nodelist[i]))
+ return Set(items, lineno=items[0].lineno)
+ else:
+ items = []
+ for i in range(1, len(nodelist), 4):
+ items.append((self.com_node(nodelist[i]),
+ self.com_node(nodelist[i+2])))
+ return Dict(items, lineno=items[0][0].lineno)
def com_apply_trailer(self, primaryNode, nodelist):
t = nodelist[1][0]
diff --git a/Lib/opcode.py b/Lib/opcode.py
index 7c3962d..f11e475 100644
--- a/Lib/opcode.py
+++ b/Lib/opcode.py
@@ -138,13 +138,13 @@
name_op('LOAD_NAME', 101) # Index in name list
def_op('BUILD_TUPLE', 102) # Number of tuple items
def_op('BUILD_LIST', 103) # Number of list items
-def_op('BUILD_MAP', 104) # Number of dict entries (upto 255)
-name_op('LOAD_ATTR', 105) # Index in name list
-def_op('COMPARE_OP', 106) # Comparison operator
-hascompare.append(106)
-name_op('IMPORT_NAME', 107) # Index in name list
-name_op('IMPORT_FROM', 108) # Index in name list
-
+def_op('BUILD_SET', 104) # Number of set items
+def_op('BUILD_MAP', 105) # Number of dict entries (upto 255)
+name_op('LOAD_ATTR', 106) # Index in name list
+def_op('COMPARE_OP', 107) # Comparison operator
+hascompare.append(107)
+name_op('IMPORT_NAME', 108) # Index in name list
+name_op('IMPORT_FROM', 109) # Index in name list
jrel_op('JUMP_FORWARD', 110) # Number of bytes to skip
jabs_op('JUMP_IF_FALSE_OR_POP', 111) # Target byte offset from beginning of code
jabs_op('JUMP_IF_TRUE_OR_POP', 112) # ""
diff --git a/Lib/symbol.py b/Lib/symbol.py
index c360e39..c0bb145 100755
--- a/Lib/symbol.py
+++ b/Lib/symbol.py
@@ -83,18 +83,19 @@
exprlist = 326
testlist = 327
dictmaker = 328
-classdef = 329
-arglist = 330
-argument = 331
-list_iter = 332
-list_for = 333
-list_if = 334
-gen_iter = 335
-gen_for = 336
-gen_if = 337
-testlist1 = 338
-encoding_decl = 339
-yield_expr = 340
+dictorsetmaker = 329
+classdef = 330
+arglist = 331
+argument = 332
+list_iter = 333
+list_for = 334
+list_if = 335
+gen_iter = 336
+gen_for = 337
+gen_if = 338
+testlist1 = 339
+encoding_decl = 340
+yield_expr = 341
#--end constants--
sym_name = {}
diff --git a/Lib/test/test_compiler.py b/Lib/test/test_compiler.py
index 24930f8..8d4a3a99 100644
--- a/Lib/test/test_compiler.py
+++ b/Lib/test/test_compiler.py
@@ -248,6 +248,7 @@
l[3:4]
d = {'a': 2}
d = {}
+s = {1}
t = ()
t = (1, 2)
l = []
diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py
index f144ae7..4713d1a 100644
--- a/Lib/test/test_grammar.py
+++ b/Lib/test/test_grammar.py
@@ -749,7 +749,7 @@
def testAtoms(self):
### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING
- ### dictmaker: test ':' test (',' test ':' test)* [',']
+ ### dictorsetmaker: (test ':' test (',' test ':' test)* [',']) | (test (',' test)* [','])
x = (1)
x = (1 or 2 or 3)
@@ -769,6 +769,11 @@
x = {'one': 1, 'two': 2,}
x = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6}
+ x = {'one'}
+ x = {'one', 1,}
+ x = {'one', 'two', 'three'}
+ x = {2, 3, 4,}
+
x = `x`
x = `1 or 2 or 3`
self.assertEqual(`1,2`, '(1, 2)')
diff --git a/Lib/test/test_parser.py b/Lib/test/test_parser.py
index a7f8fc2..03803d9 100644
--- a/Lib/test/test_parser.py
+++ b/Lib/test/test_parser.py
@@ -59,7 +59,20 @@
def test_expressions(self):
self.check_expr("foo(1)")
+ self.check_expr("{1:1}")
+ self.check_expr("{1:1, 2:2, 3:3}")
+ self.check_expr("{1:1, 2:2, 3:3,}")
+ self.check_expr("{1}")
+ self.check_expr("{1, 2, 3}")
+ self.check_expr("{1, 2, 3,}")
+ self.check_expr("[]")
+ self.check_expr("[1]")
self.check_expr("[1, 2, 3]")
+ self.check_expr("[1, 2, 3,]")
+ self.check_expr("()")
+ self.check_expr("(1,)")
+ self.check_expr("(1, 2, 3)")
+ self.check_expr("(1, 2, 3,)")
self.check_expr("[x**3 for x in range(20)]")
self.check_expr("[x**3 for x in range(20) if x % 3]")
self.check_expr("[x**3 for x in range(20) if x % 2 if x % 3]")