Index: Python/ceval.c =================================================================== --- Python/ceval.c (revision 54401) +++ Python/ceval.c (working copy) @@ -117,7 +117,6 @@ static PyObject * cmp_outcome(int, PyObject *, PyObject *); static PyObject * import_from(PyObject *, PyObject *); static int import_all_from(PyObject *, PyObject *); -static PyObject * build_class(PyObject *, PyObject *, PyObject *); static void set_exc_info(PyThreadState *, PyObject *, PyObject *, PyObject *); static void reset_exc_info(PyThreadState *); static void format_exc_check_arg(PyObject *, char *, PyObject *); @@ -1532,14 +1531,12 @@ } break; - case LOAD_LOCALS: - if ((x = f->f_locals) != NULL) { - Py_INCREF(x); - PUSH(x); - continue; - } - PyErr_SetString(PyExc_SystemError, "no locals"); - break; + case STORE_LOCALS: + x = POP(); + v = f->f_locals; + Py_XDECREF(v); + f->f_locals = x; + continue; case RETURN_VALUE: retval = POP(); @@ -1586,16 +1583,16 @@ Py_DECREF(v); break; - case BUILD_CLASS: - u = TOP(); - v = SECOND(); - w = THIRD(); - STACKADJ(-2); - x = build_class(u, v, w); - SET_TOP(x); - Py_DECREF(u); - Py_DECREF(v); - Py_DECREF(w); + case LOAD_BUILD_CLASS: + x = PyDict_GetItemString(f->f_builtins, + "__build_class__"); + if (x == NULL) { + PyErr_SetString(PyExc_ImportError, + "__build_class__ not found"); + break; + } + Py_INCREF(x); + PUSH(x); break; case STORE_NAME: @@ -4023,60 +4020,6 @@ return err; } -static PyObject * -build_class(PyObject *methods, PyObject *bases, PyObject *name) -{ - PyObject *metaclass = NULL, *result, *base; - - if (PyDict_Check(methods)) - metaclass = PyDict_GetItemString(methods, "__metaclass__"); - if (metaclass != NULL) - Py_INCREF(metaclass); - else if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) { - base = PyTuple_GET_ITEM(bases, 0); - metaclass = PyObject_GetAttrString(base, "__class__"); - if (metaclass == NULL) { - PyErr_Clear(); - metaclass = (PyObject *)base->ob_type; - Py_INCREF(metaclass); - } - } - else { - PyObject *g = PyEval_GetGlobals(); - if (g != NULL && PyDict_Check(g)) - metaclass = PyDict_GetItemString(g, "__metaclass__"); - if (metaclass == NULL) - metaclass = (PyObject *) &PyType_Type; - Py_INCREF(metaclass); - } - result = PyObject_CallFunctionObjArgs(metaclass, name, bases, methods, - NULL); - Py_DECREF(metaclass); - if (result == NULL && PyErr_ExceptionMatches(PyExc_TypeError)) { - /* A type error here likely means that the user passed - in a base that was not a class (such the random module - instead of the random.random type). Help them out with - by augmenting the error message with more information.*/ - - PyObject *ptype, *pvalue, *ptraceback; - - PyErr_Fetch(&ptype, &pvalue, &ptraceback); - if (PyString_Check(pvalue)) { - PyObject *newmsg; - newmsg = PyString_FromFormat( - "Error when calling the metaclass bases\n" - " %s", - PyString_AS_STRING(pvalue)); - if (newmsg != NULL) { - Py_DECREF(pvalue); - pvalue = newmsg; - } - } - PyErr_Restore(ptype, pvalue, ptraceback); - } - return result; -} - static void format_exc_check_arg(PyObject *exc, char *format_str, PyObject *obj) { Index: Python/graminit.c =================================================================== --- Python/graminit.c (revision 54401) +++ Python/graminit.c (working copy) @@ -1635,7 +1635,7 @@ {23, 4}, }; static arc arcs_76_3[2] = { - {9, 5}, + {14, 5}, {15, 6}, }; static arc arcs_76_4[1] = { Index: Python/ast.c =================================================================== --- Python/ast.c (revision 54401) +++ Python/ast.c (working copy) @@ -2092,28 +2092,6 @@ return ast_for_testlist(c, n); } -/* like ast_for_testlist() but returns a sequence */ -static asdl_seq* -ast_for_class_bases(struct compiling *c, const node* n) -{ - /* testlist: test (',' test)* [','] */ - assert(NCH(n) > 0); - REQ(n, testlist); - if (NCH(n) == 1) { - expr_ty base; - asdl_seq *bases = asdl_seq_new(1, c->c_arena); - if (!bases) - return NULL; - base = ast_for_expr(c, CHILD(n, 0)); - if (!base) - return NULL; - asdl_seq_SET(bases, 0, base); - return bases; - } - - return seq_for_testlist(c, n); -} - static stmt_ty ast_for_expr_stmt(struct compiling *c, const node *n) { @@ -3032,9 +3010,10 @@ static stmt_ty ast_for_classdef(struct compiling *c, const node *n) { - /* classdef: 'class' NAME ['(' testlist ')'] ':' suite */ - asdl_seq *bases, *s; - + /* classdef: 'class' NAME ['(' arglist ')'] ':' suite */ + asdl_seq *s; + expr_ty call, dummy; + REQ(n, classdef); if (!strcmp(STR(CHILD(n, 1)), "None")) { @@ -3042,32 +3021,36 @@ return NULL; } - if (NCH(n) == 4) { + if (NCH(n) == 4) { /* class NAME ':' suite */ s = ast_for_suite(c, CHILD(n, 3)); if (!s) return NULL; - return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), NULL, s, LINENO(n), - n->n_col_offset, c->c_arena); + return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), NULL, NULL, NULL, NULL, s, + LINENO(n), n->n_col_offset, c->c_arena); } - /* check for empty base list */ - if (TYPE(CHILD(n,3)) == RPAR) { + + if (TYPE(CHILD(n, 3)) == RPAR) { /* class NAME '(' ')' ':' suite */ s = ast_for_suite(c, CHILD(n,5)); if (!s) return NULL; - return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), NULL, s, LINENO(n), - n->n_col_offset, c->c_arena); + return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), NULL, NULL, NULL, NULL, s, + LINENO(n), n->n_col_offset, c->c_arena); } - /* else handle the base class list */ - bases = ast_for_class_bases(c, CHILD(n, 3)); - if (!bases) + /* class NAME '(' arglist ')' ':' suite */ + /* build up a fake Call node so we can extract its pieces */ + dummy = Name(NEW_IDENTIFIER(CHILD(n, 1)), Load, LINENO(n), n->n_col_offset, c->c_arena); + call = ast_for_call(c, CHILD(n, 3), dummy); + if (!call) return NULL; - s = ast_for_suite(c, CHILD(n, 6)); if (!s) return NULL; - return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), bases, s, LINENO(n), - n->n_col_offset, c->c_arena); + + return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), + call->v.Call.args, call->v.Call.keywords, + call->v.Call.starargs, call->v.Call.kwargs, s, + LINENO(n), n->n_col_offset, c->c_arena); } static stmt_ty Index: Python/import.c =================================================================== --- Python/import.c (revision 54401) +++ Python/import.c (working copy) @@ -72,9 +72,10 @@ 3030 (added keyword-only parameters) 3040 (added signature annotations) 3050 (print becomes a function) + 3060 (PEP 3115 metaclass syntax) . */ -#define MAGIC (3050 | ((long)'\r'<<16) | ((long)'\n'<<24)) +#define MAGIC (3060 | ((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 Index: Python/symtable.c =================================================================== --- Python/symtable.c (revision 54401) +++ Python/symtable.c (working copy) @@ -983,6 +983,11 @@ if (!symtable_add_def(st, s->v.ClassDef.name, DEF_LOCAL)) return 0; VISIT_SEQ(st, expr, s->v.ClassDef.bases); + VISIT_SEQ(st, expr, s->v.ClassDef.keywords); + if (s->v.ClassDef.starargs) + VISIT(st, expr, s->v.ClassDef.starargs); + if (s->v.ClassDef.kwargs) + VISIT(st, expr, s->v.ClassDef.kwargs); if (!symtable_enter_block(st, s->v.ClassDef.name, ClassBlock, (void *)s, s->lineno)) return 0; Index: Python/compile.c =================================================================== --- Python/compile.c (revision 54401) +++ Python/compile.c (working copy) @@ -176,6 +176,11 @@ static int expr_constant(expr_ty e); static int compiler_with(struct compiler *, stmt_ty); +static int compiler_call_helper(struct compiler *c, int n, + asdl_seq *args, + asdl_seq *keywords, + expr_ty starargs, + expr_ty kwargs); static PyCodeObject *assemble(struct compiler *, int addNone); static PyObject *__doc__; @@ -734,6 +739,8 @@ case PRINT_EXPR: return -1; + case LOAD_BUILD_CLASS: + return 1; case INPLACE_LSHIFT: case INPLACE_RSHIFT: case INPLACE_AND: @@ -744,8 +751,8 @@ return 0; case WITH_CLEANUP: return -1; /* XXX Sometimes more */ - case LOAD_LOCALS: - return 1; + case STORE_LOCALS: + return -1; case RETURN_VALUE: return -1; case IMPORT_STAR: @@ -757,8 +764,6 @@ return 0; case END_FINALLY: return -1; /* or -2 or -3 if exception occurred */ - case BUILD_CLASS: - return -2; case STORE_NAME: return -1; @@ -1509,54 +1514,107 @@ static int compiler_class(struct compiler *c, stmt_ty s) { - int n; + static PyObject *build_class = NULL; + static PyObject *locals = NULL; PyCodeObject *co; PyObject *str; - /* push class name on stack, needed by BUILD_CLASS */ - ADDOP_O(c, LOAD_CONST, s->v.ClassDef.name, consts); - /* push the tuple of base classes on the stack */ - n = asdl_seq_LEN(s->v.ClassDef.bases); - if (n > 0) - VISIT_SEQ(c, expr, s->v.ClassDef.bases); - ADDOP_I(c, BUILD_TUPLE, n); - if (!compiler_enter_scope(c, s->v.ClassDef.name, (void *)s, - s->lineno)) - return 0; - c->u->u_private = s->v.ClassDef.name; - Py_INCREF(c->u->u_private); - str = PyString_InternFromString("__name__"); - if (!str || !compiler_nameop(c, str, Load)) { - Py_XDECREF(str); - compiler_exit_scope(c); - return 0; + PySTEntryObject *ste; + + /* initialize statics */ + if (build_class == NULL) { + build_class = PyString_FromString("__build_class__"); + if (build_class == NULL) + return 0; } - - Py_DECREF(str); - str = PyString_InternFromString("__module__"); - if (!str || !compiler_nameop(c, str, Store)) { - Py_XDECREF(str); - compiler_exit_scope(c); - return 0; + if (locals == NULL) { + locals = PyString_FromString("__locals__"); + if (locals == NULL) + return 0; } - Py_DECREF(str); - if (!compiler_body(c, s->v.ClassDef.body)) { - compiler_exit_scope(c); + /* ultimately generate code for: + = __build_class__(, , *, **) + where: + is a function/closure created from the class body + is the class name + is the positional arguments and *varargs argument + is the keyword arguments and **kwds argument + This borrows from compiler_call. + */ + + /* 0. Create a fake variable named __locals__ */ + ste = PySymtable_Lookup(c->c_st, s); + if (ste == NULL) return 0; + assert(PyList_Check(ste->ste_varnames)); + if (PyList_Append(ste->ste_varnames, locals) < 0) + return 0; + + /* 1. compile the class body into a code object */ + if (!compiler_enter_scope(c, s->v.ClassDef.name, (void *)s, s->lineno)) + return 0; + /* this block represents what we do in the new scope */ + { + /* use the class name for name mangling */ + Py_INCREF(s->v.ClassDef.name); + c->u->u_private = s->v.ClassDef.name; + /* force it to have one mandatory argument */ + c->u->u_argcount = 1; + /* load the first argument ... */ + ADDOP_I(c, LOAD_FAST, 0); + /* ... and store it into f_locals */ + ADDOP_IN_SCOPE(c, STORE_LOCALS); + /* load __name__ ... */ + str = PyString_InternFromString("__name__"); + if (!str || !compiler_nameop(c, str, Load)) { + Py_XDECREF(str); + compiler_exit_scope(c); + return 0; + } + Py_DECREF(str); + /* ... and store it as __module__ */ + str = PyString_InternFromString("__module__"); + if (!str || !compiler_nameop(c, str, Store)) { + Py_XDECREF(str); + compiler_exit_scope(c); + return 0; + } + Py_DECREF(str); + /* compile the body proper */ + if (!compiler_body(c, s->v.ClassDef.body)) { + compiler_exit_scope(c); + return 0; + } + /* return None */ + ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP_IN_SCOPE(c, RETURN_VALUE); + /* create the code object */ + co = assemble(c, 1); } - - ADDOP_IN_SCOPE(c, LOAD_LOCALS); - ADDOP_IN_SCOPE(c, RETURN_VALUE); - co = assemble(c, 1); + /* leave the new scope */ compiler_exit_scope(c); if (co == NULL) return 0; + /* 2. load the 'build_class' function */ + ADDOP(c, LOAD_BUILD_CLASS); + + /* 3. load a function (or closure) made from the code object */ compiler_make_closure(c, co, 0); Py_DECREF(co); - ADDOP_I(c, CALL_FUNCTION, 0); - ADDOP(c, BUILD_CLASS); + /* 4. load class name */ + ADDOP_O(c, LOAD_CONST, s->v.ClassDef.name, consts); + + /* 5. generate the rest of the code for the call */ + if (!compiler_call_helper(c, 2, + s->v.ClassDef.bases, + s->v.ClassDef.keywords, + s->v.ClassDef.starargs, + s->v.ClassDef.kwargs)) + return 0; + + /* 6. store into */ if (!compiler_nameop(c, s->v.ClassDef.name, Store)) return 0; return 1; @@ -2613,21 +2671,37 @@ static int compiler_call(struct compiler *c, expr_ty e) { - int n, code = 0; + VISIT(c, expr, e->v.Call.func); + return compiler_call_helper(c, 0, + e->v.Call.args, + e->v.Call.keywords, + e->v.Call.starargs, + e->v.Call.kwargs); +} - VISIT(c, expr, e->v.Call.func); - n = asdl_seq_LEN(e->v.Call.args); - VISIT_SEQ(c, expr, e->v.Call.args); - if (e->v.Call.keywords) { - VISIT_SEQ(c, keyword, e->v.Call.keywords); - n |= asdl_seq_LEN(e->v.Call.keywords) << 8; +/* shared code between compiler_call and compiler_class */ +static int +compiler_call_helper(struct compiler *c, + int n, /* Args already pushed */ + asdl_seq *args, + asdl_seq *keywords, + expr_ty starargs, + expr_ty kwargs) +{ + int code = 0; + + n += asdl_seq_LEN(args); + VISIT_SEQ(c, expr, args); + if (keywords) { + VISIT_SEQ(c, keyword, keywords); + n |= asdl_seq_LEN(keywords) << 8; } - if (e->v.Call.starargs) { - VISIT(c, expr, e->v.Call.starargs); + if (starargs) { + VISIT(c, expr, starargs); code |= 1; } - if (e->v.Call.kwargs) { - VISIT(c, expr, e->v.Call.kwargs); + if (kwargs) { + VISIT(c, expr, kwargs); code |= 2; } switch (code) { Index: Python/Python-ast.c =================================================================== --- Python/Python-ast.c (revision 54401) +++ Python/Python-ast.c (working copy) @@ -49,6 +49,9 @@ static char *ClassDef_fields[]={ "name", "bases", + "keywords", + "starargs", + "kwargs", "body", }; static PyTypeObject *Return_type; @@ -477,7 +480,7 @@ FunctionDef_type = make_type("FunctionDef", stmt_type, FunctionDef_fields, 5); if (!FunctionDef_type) return 0; - ClassDef_type = make_type("ClassDef", stmt_type, ClassDef_fields, 3); + ClassDef_type = make_type("ClassDef", stmt_type, ClassDef_fields, 6); if (!ClassDef_type) return 0; Return_type = make_type("Return", stmt_type, Return_fields, 1); if (!Return_type) return 0; @@ -835,8 +838,9 @@ } stmt_ty -ClassDef(identifier name, asdl_seq * bases, asdl_seq * body, int lineno, int - col_offset, PyArena *arena) +ClassDef(identifier name, asdl_seq * bases, asdl_seq * keywords, expr_ty + starargs, expr_ty kwargs, asdl_seq * body, int lineno, int col_offset, + PyArena *arena) { stmt_ty p; if (!name) { @@ -850,6 +854,9 @@ p->kind = ClassDef_kind; p->v.ClassDef.name = name; p->v.ClassDef.bases = bases; + p->v.ClassDef.keywords = keywords; + p->v.ClassDef.starargs = starargs; + p->v.ClassDef.kwargs = kwargs; p->v.ClassDef.body = body; p->lineno = lineno; p->col_offset = col_offset; @@ -1974,6 +1981,21 @@ if (PyObject_SetAttrString(result, "bases", value) == -1) goto failed; Py_DECREF(value); + value = ast2obj_list(o->v.ClassDef.keywords, ast2obj_keyword); + if (!value) goto failed; + if (PyObject_SetAttrString(result, "keywords", value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->v.ClassDef.starargs); + if (!value) goto failed; + if (PyObject_SetAttrString(result, "starargs", value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->v.ClassDef.kwargs); + if (!value) goto failed; + if (PyObject_SetAttrString(result, "kwargs", value) == -1) + goto failed; + Py_DECREF(value); value = ast2obj_list(o->v.ClassDef.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttrString(result, "body", value) == -1) Index: Python/bltinmodule.c =================================================================== --- Python/bltinmodule.c (revision 54401) +++ Python/bltinmodule.c (working copy) @@ -31,6 +31,118 @@ static PyObject *filtertuple (PyObject *, PyObject *); static PyObject * +builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds) +{ + PyObject *func, *name, *bases, *metaclass, *prep, *namespace, *res; + Py_ssize_t nargs, nbases; + + assert(args != NULL); + if (!PyTuple_Check(args)) { + PyErr_SetString(PyExc_TypeError, + "__build_class__: args is not a tuple"); + return NULL; + } + nargs = PyTuple_GET_SIZE(args); + if (nargs < 2) { + PyErr_SetString(PyExc_TypeError, + "__build_class__: not enough arguments"); + return NULL; + } + func = PyTuple_GET_ITEM(args, 0); /* Better be callable */ + name = PyTuple_GET_ITEM(args, 1); + if (!PyString_Check(name)) { + PyErr_SetString(PyExc_TypeError, + "__build_class__: name is not a string"); + return NULL; + } + bases = PyTuple_GetSlice(args, 2, nargs); + if (bases == NULL) + return NULL; + nbases = nargs - 2; + + if (kwds == NULL) + metaclass = NULL; + else { + metaclass = PyDict_GetItemString(kwds, "metaclass"); + if (metaclass != NULL) { + Py_INCREF(metaclass); + if (PyDict_DelItemString(kwds, "metaclass") < 0) { + Py_DECREF(metaclass); + Py_DECREF(bases); + return NULL; + } + } + } + if (metaclass == NULL) { + if (PyTuple_GET_SIZE(bases) == 0) + metaclass = (PyObject *) (&PyType_Type); + else { + PyObject *base0 = PyTuple_GET_ITEM(bases, 0); + metaclass = (PyObject *) (base0->ob_type); + } + Py_INCREF(metaclass); + } + prep = PyObject_GetAttrString(metaclass, "__prepare__"); + if (prep == NULL) { + PyErr_Clear(); + namespace = PyDict_New(); + } + else { + PyObject *pargs; + int i; + pargs = PyTuple_New(nargs-1); + if (pargs == NULL) { + Py_DECREF(prep); + Py_DECREF(metaclass); + Py_DECREF(bases); + return NULL; + } + Py_INCREF(name); + PyTuple_SET_ITEM(pargs, 0, name); + for (i = 0; i < nbases; i++) { + PyObject *base = PyTuple_GET_ITEM(bases, i); + Py_INCREF(base); + PyTuple_SET_ITEM(pargs, i+1, base); + } + namespace = PyEval_CallObjectWithKeywords(prep, pargs, kwds); + Py_DECREF(pargs); + Py_DECREF(prep); + if (namespace == NULL) { + Py_DECREF(metaclass); + Py_DECREF(bases); + return NULL; + } + } + res = PyObject_CallFunctionObjArgs(func, namespace, NULL); + if (res != NULL) { + PyObject *margs; + Py_DECREF(res); + res = NULL; + margs = PyTuple_New(3); + if (margs != NULL) { + Py_INCREF(name); + PyTuple_SET_ITEM(margs, 0, name); + Py_INCREF(bases); + PyTuple_SET_ITEM(margs, 1, bases); + Py_INCREF(namespace); + PyTuple_SET_ITEM(margs, 2, namespace); + res = PyEval_CallObjectWithKeywords(metaclass, + margs, kwds); + Py_DECREF(margs); + } + } + Py_DECREF(namespace); + Py_DECREF(metaclass); + Py_DECREF(bases); + return res; +} + +PyDoc_STRVAR(build_class_doc, +"__build_class__(func, name, *bases, metaclass=None, **kwds) -> class\n\ +\n\ +Internal helper function used by the class statement."); + +static PyObject * builtin___import__(PyObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"name", "globals", "locals", "fromlist", @@ -2103,6 +2215,8 @@ static PyMethodDef builtin_methods[] = { + {"__build_class__", (PyCFunction)builtin___build_class__, + METH_VARARGS | METH_KEYWORDS, build_class_doc}, {"__import__", (PyCFunction)builtin___import__, METH_VARARGS | METH_KEYWORDS, import_doc}, {"abs", builtin_abs, METH_O, abs_doc}, {"all", builtin_all, METH_O, all_doc}, Index: Include/opcode.h =================================================================== --- Include/opcode.h (revision 54401) +++ Include/opcode.h (working copy) @@ -59,8 +59,9 @@ #define BINARY_OR 66 #define INPLACE_POWER 67 #define GET_ITER 68 - +#define STORE_LOCALS 69 #define PRINT_EXPR 70 +#define LOAD_BUILD_CLASS 71 #define INPLACE_LSHIFT 75 #define INPLACE_RSHIFT 76 @@ -69,14 +70,13 @@ #define INPLACE_OR 79 #define BREAK_LOOP 80 #define WITH_CLEANUP 81 -#define LOAD_LOCALS 82 + #define RETURN_VALUE 83 #define IMPORT_STAR 84 #define MAKE_BYTES 85 #define YIELD_VALUE 86 #define POP_BLOCK 87 #define END_FINALLY 88 -#define BUILD_CLASS 89 #define HAVE_ARGUMENT 90 /* Opcodes from here have an argument: */ @@ -120,10 +120,10 @@ #define RAISE_VARARGS 130 /* Number of raise arguments (1, 2 or 3) */ /* CALL_FUNCTION_XXX opcodes defined below depend on this definition */ #define CALL_FUNCTION 131 /* #args + (#kwargs<<8) */ -#define MAKE_FUNCTION 132 /* #defaults */ +#define MAKE_FUNCTION 132 /* #defaults + #kwdefaults<<8 + #annotations<<16 */ #define BUILD_SLICE 133 /* Number of items */ -#define MAKE_CLOSURE 134 /* #free vars */ +#define MAKE_CLOSURE 134 /* same as MAKE_FUNCTION */ #define LOAD_CLOSURE 135 /* Load free variable from closure */ #define LOAD_DEREF 136 /* Load and dereference from closure cell */ #define STORE_DEREF 137 /* Store into cell */ Index: Include/Python-ast.h =================================================================== --- Include/Python-ast.h (revision 54401) +++ Include/Python-ast.h (working copy) @@ -82,6 +82,9 @@ struct { identifier name; asdl_seq *bases; + asdl_seq *keywords; + expr_ty starargs; + expr_ty kwargs; asdl_seq *body; } ClassDef; @@ -380,8 +383,9 @@ stmt_ty _Py_FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq * decorators, expr_ty returns, int lineno, int col_offset, PyArena *arena); -#define ClassDef(a0, a1, a2, a3, a4, a5) _Py_ClassDef(a0, a1, a2, a3, a4, a5) -stmt_ty _Py_ClassDef(identifier name, asdl_seq * bases, asdl_seq * body, int +#define ClassDef(a0, a1, a2, a3, a4, a5, a6, a7, a8) _Py_ClassDef(a0, a1, a2, a3, a4, a5, a6, a7, a8) +stmt_ty _Py_ClassDef(identifier name, asdl_seq * bases, asdl_seq * keywords, + expr_ty starargs, expr_ty kwargs, asdl_seq * body, int lineno, int col_offset, PyArena *arena); #define Return(a0, a1, a2, a3) _Py_Return(a0, a1, a2, a3) stmt_ty _Py_Return(expr_ty value, int lineno, int col_offset, PyArena *arena); Index: Grammar/Grammar =================================================================== --- Grammar/Grammar (revision 54401) +++ Grammar/Grammar (working copy) @@ -119,7 +119,7 @@ testlist: test (',' test)* [','] dictsetmaker: (test ':' test (',' test ':' test)* [',']) | (test (',' test)* [',']) -classdef: 'class' NAME ['(' [testlist] ')'] ':' suite +classdef: 'class' NAME ['(' [arglist] ')'] ':' suite arglist: (argument ',')* (argument [',']| '*' test [',' '**' test] | '**' test) argument: test [gen_for] | test '=' test # Really [keyword '='] test Index: Parser/Python.asdl =================================================================== --- Parser/Python.asdl (revision 54401) +++ Parser/Python.asdl (working copy) @@ -11,7 +11,12 @@ stmt = FunctionDef(identifier name, arguments args, stmt* body, expr* decorators, expr? returns) - | ClassDef(identifier name, expr* bases, stmt* body) + | ClassDef(identifier name, + expr* bases, + keyword* keywords, + expr? starargs, + expr? kwargs, + stmt* body) | Return(expr? value) | Delete(expr* targets) Index: Lib/opcode.py =================================================================== --- Lib/opcode.py (revision 54401) +++ Lib/opcode.py (working copy) @@ -98,8 +98,10 @@ def_op('BINARY_OR', 66) def_op('INPLACE_POWER', 67) def_op('GET_ITER', 68) +def_op('STORE_LOCALS', 69) def_op('PRINT_EXPR', 70) +def_op('LOAD_BUILD_CLASS', 71) def_op('INPLACE_LSHIFT', 75) def_op('INPLACE_RSHIFT', 76) @@ -108,14 +110,13 @@ def_op('INPLACE_OR', 79) def_op('BREAK_LOOP', 80) def_op('WITH_CLEANUP', 81) -def_op('LOAD_LOCALS', 82) + def_op('RETURN_VALUE', 83) def_op('IMPORT_STAR', 84) def_op('MAKE_BYTES', 85) def_op('YIELD_VALUE', 86) def_op('POP_BLOCK', 87) def_op('END_FINALLY', 88) -def_op('BUILD_CLASS', 89) HAVE_ARGUMENT = 90 # Opcodes from here have an argument: Index: Modules/_bsddb.c =================================================================== --- Modules/_bsddb.c (revision 54401) +++ Modules/_bsddb.c (working copy) @@ -5991,6 +5991,10 @@ * from both DBError and KeyError, since the API only supports * using one base class. */ PyDict_SetItemString(d, "KeyError", PyExc_KeyError); + { + PyObject *builtin_mod = PyImport_ImportModule("__builtin__"); + PyDict_SetItemString(d, "__builtins__", builtin_mod); + } PyRun_String("class DBNotFoundError(DBError, KeyError): pass\n" "class DBKeyEmptyError(DBError, KeyError): pass", Py_file_input, d, d);