SF patch 1547796 by Georg Brandl -- set literals.
diff --git a/Python/Python-ast.c b/Python/Python-ast.c
index 68523e4..86f09ed 100644
--- a/Python/Python-ast.c
+++ b/Python/Python-ast.c
@@ -178,6 +178,10 @@
         "keys",
         "values",
 };
+static PyTypeObject *Set_type;
+static char *Set_fields[]={
+        "elts",
+};
 static PyTypeObject *ListComp_type;
 static char *ListComp_fields[]={
         "elt",
@@ -517,6 +521,8 @@
         if (!IfExp_type) return 0;
         Dict_type = make_type("Dict", expr_type, Dict_fields, 2);
         if (!Dict_type) return 0;
+        Set_type = make_type("Set", expr_type, Set_fields, 1);
+        if (!Set_type) return 0;
         ListComp_type = make_type("ListComp", expr_type, ListComp_fields, 2);
         if (!ListComp_type) return 0;
         GeneratorExp_type = make_type("GeneratorExp", expr_type,
@@ -1435,6 +1441,22 @@
 }
 
 expr_ty
+Set(asdl_seq * elts, int lineno, int col_offset, PyArena *arena)
+{
+        expr_ty p;
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+        if (!p) {
+                PyErr_NoMemory();
+                return NULL;
+        }
+        p->kind = Set_kind;
+        p->v.Set.elts = elts;
+        p->lineno = lineno;
+        p->col_offset = col_offset;
+        return p;
+}
+
+expr_ty
 ListComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset,
          PyArena *arena)
 {
@@ -2424,6 +2446,15 @@
                         goto failed;
                 Py_DECREF(value);
                 break;
+        case Set_kind:
+                result = PyType_GenericNew(Set_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.Set.elts, ast2obj_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "elts", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
         case ListComp_kind:
                 result = PyType_GenericNew(ListComp_type, NULL, NULL);
                 if (!result) goto failed;
@@ -3069,6 +3100,7 @@
             return;
         if (PyDict_SetItemString(d, "IfExp", (PyObject*)IfExp_type) < 0) return;
         if (PyDict_SetItemString(d, "Dict", (PyObject*)Dict_type) < 0) return;
+        if (PyDict_SetItemString(d, "Set", (PyObject*)Set_type) < 0) return;
         if (PyDict_SetItemString(d, "ListComp", (PyObject*)ListComp_type) < 0)
             return;
         if (PyDict_SetItemString(d, "GeneratorExp",
diff --git a/Python/ast.c b/Python/ast.c
index 1a43878..cd0a81d 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -394,6 +394,7 @@
             expr_name = "list comprehension";
             break;
         case Dict_kind:
+	case Set_kind:
         case Num_kind:
         case Str_kind:
             expr_name = "literal";
@@ -1187,7 +1188,7 @@
 ast_for_atom(struct compiling *c, const node *n)
 {
     /* atom: '(' [yield_expr|testlist_gexp] ')' | '[' [listmaker] ']'
-       | '{' [dictmaker] '}' | NAME | NUMBER | STRING+
+       | '{' [dictsetmaker] '}' | NAME | NUMBER | STRING+
     */
     node *ch = CHILD(n, 0);
     
@@ -1242,36 +1243,55 @@
 	else
 	    return ast_for_listcomp(c, ch);
     case LBRACE: {
-	/* dictmaker: test ':' test (',' test ':' test)* [','] */
+	/* dictsetmaker: test ':' test (',' test ':' test)* [','] |
+	 *               test (',' test)* [',']  */
 	int i, size;
 	asdl_seq *keys, *values;
 	
 	ch = CHILD(n, 1);
-	size = (NCH(ch) + 1) / 4; /* +1 in case no trailing comma */
-	keys = asdl_seq_new(size, c->c_arena);
-	if (!keys)
-	    return NULL;
-	
-	values = asdl_seq_new(size, c->c_arena);
-	if (!values)
-	    return NULL;
-	
-	for (i = 0; i < NCH(ch); i += 4) {
-	    expr_ty expression;
-	    
-	    expression = ast_for_expr(c, CHILD(ch, i));
-	    if (!expression)
-		return NULL;
+	if (NCH(ch) == 1 || (NCH(ch) > 0 && STR(CHILD(ch, 1))[0] == ',')) {
+            /* it's a set */
+            size = (NCH(ch) + 1) / 2; /* +1 in case no trailing comma */
+            keys = asdl_seq_new(size, c->c_arena);
+            if (!keys)
+                return NULL;
 
-	    asdl_seq_SET(keys, i / 4, expression);
+            for (i = 0; i < NCH(ch); i += 2) {
+                expr_ty expression;
+                expression = ast_for_expr(c, CHILD(ch, i));
+                if (!expression)
+                    return NULL;
+                asdl_seq_SET(keys, i / 2, expression);
+            }
+            return Set(keys, LINENO(n), n->n_col_offset, c->c_arena);
+        } else {
+            /* it's a dict */
+            size = (NCH(ch) + 1) / 4; /* +1 in case no trailing comma */
+            keys = asdl_seq_new(size, c->c_arena);
+            if (!keys)
+                return NULL;
+            
+            values = asdl_seq_new(size, c->c_arena);
+            if (!values)
+                return NULL;
+            
+            for (i = 0; i < NCH(ch); i += 4) {
+                expr_ty expression;
+                
+                expression = ast_for_expr(c, CHILD(ch, i));
+                if (!expression)
+                    return NULL;
 
-	    expression = ast_for_expr(c, CHILD(ch, i + 2));
-	    if (!expression)
-		return NULL;
+                asdl_seq_SET(keys, i / 4, expression);
 
-	    asdl_seq_SET(values, i / 4, expression);
-	}
-	return Dict(keys, values, LINENO(n), n->n_col_offset, c->c_arena);
+                expression = ast_for_expr(c, CHILD(ch, i + 2));
+                if (!expression)
+                    return NULL;
+
+                asdl_seq_SET(values, i / 4, expression);
+            }
+            return Dict(keys, values, LINENO(n), n->n_col_offset, c->c_arena);
+        }
     }
     default:
 	PyErr_Format(PyExc_SystemError, "unhandled atom %d", TYPE(ch));
diff --git a/Python/ceval.c b/Python/ceval.c
index 95def9a..25e6a0b 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -1945,6 +1945,24 @@
 			}
 			break;
 
+		case BUILD_SET:
+			x = PySet_New(NULL);
+			if (x != NULL) {
+				for (; --oparg >= 0;) {
+					w = POP();
+					if (err == 0)
+						err = PySet_Add(x, w);
+					Py_DECREF(w);
+				}
+				if (err != 0) {
+					Py_DECREF(x);
+					break;
+				}
+				PUSH(x);
+				continue;
+			}
+			break;
+
 		case BUILD_MAP:
 			x = PyDict_New();
 			PUSH(x);
diff --git a/Python/compile.c b/Python/compile.c
index 4601f2c..945a281 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -851,6 +851,7 @@
 			return 1;
 		case BUILD_TUPLE:
 		case BUILD_LIST:
+		case BUILD_SET:
 			return 1-oparg;
 		case BUILD_MAP:
 			return 1;
@@ -2955,6 +2956,11 @@
 			ADDOP(c, STORE_SUBSCR);
 		}
 		break;
+	case Set_kind:
+		n = asdl_seq_LEN(e->v.Set.elts);
+		VISIT_SEQ(c, expr, e->v.Set.elts);
+		ADDOP_I(c, BUILD_SET, n);
+		break;
 	case ListComp_kind:
 		return compiler_listcomp(c, e);
 	case GeneratorExp_kind:
diff --git a/Python/graminit.c b/Python/graminit.c
index cfbd7a4..aeaa429 100644
--- a/Python/graminit.c
+++ b/Python/graminit.c
@@ -1500,26 +1500,42 @@
 static arc arcs_71_0[1] = {
 	{26, 1},
 };
-static arc arcs_71_1[1] = {
+static arc arcs_71_1[3] = {
 	{21, 2},
+	{27, 3},
+	{0, 1},
 };
 static arc arcs_71_2[1] = {
-	{26, 3},
+	{26, 4},
 };
 static arc arcs_71_3[2] = {
-	{27, 4},
+	{26, 5},
 	{0, 3},
 };
 static arc arcs_71_4[2] = {
-	{26, 1},
+	{27, 6},
 	{0, 4},
 };
-static state states_71[5] = {
+static arc arcs_71_5[2] = {
+	{27, 3},
+	{0, 5},
+};
+static arc arcs_71_6[2] = {
+	{26, 7},
+	{0, 6},
+};
+static arc arcs_71_7[1] = {
+	{21, 2},
+};
+static state states_71[8] = {
 	{1, arcs_71_0},
-	{1, arcs_71_1},
+	{3, arcs_71_1},
 	{1, arcs_71_2},
 	{2, arcs_71_3},
 	{2, arcs_71_4},
+	{2, arcs_71_5},
+	{2, arcs_71_6},
+	{1, arcs_71_7},
 };
 static arc arcs_72_0[1] = {
 	{157, 1},
@@ -1911,7 +1927,7 @@
 	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\140\010\311\000\000"},
 	{326, "testlist", 0, 3, states_70,
 	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\020\004\000\140\010\311\000\000"},
-	{327, "dictmaker", 0, 5, states_71,
+	{327, "dictsetmaker", 0, 8, states_71,
 	 "\000\040\010\000\000\000\000\000\000\000\000\000\000\020\004\000\140\010\311\000\000"},
 	{328, "classdef", 0, 8, states_72,
 	 "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\040\000"},
diff --git a/Python/import.c b/Python/import.c
index d80611e..49e844a 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -66,9 +66,10 @@
        			    storing constants that should have been removed)
        Python 3000:   3000
        	              3010 (removed UNARY_CONVERT)
+		      3020 (added BUILD_SET)
 .
 */
-#define MAGIC (3010 | ((long)'\r'<<16) | ((long)'\n'<<24))
+#define MAGIC (3020 | ((long)'\r'<<16) | ((long)'\n'<<24))
 
 /* Magic word as global; note that _PyImport_Init() can change the
    value of this global to accommodate for alterations of how the