diff options
| author | Guido van Rossum <guido@python.org> | 2007-03-18 15:41:51 +0000 | 
|---|---|---|
| committer | Guido van Rossum <guido@python.org> | 2007-03-18 15:41:51 +0000 | 
| commit | 52cc1d838f4fee573e57b5b182d8e5f5db63240f (patch) | |
| tree | 0ea50468d2b04ee12131c155c5918e8a70dafe1c /Python | |
| parent | ef17c16b366b09a78dfe5fc5171fe2b0b29f60e5 (diff) | |
| download | cpython-git-52cc1d838f4fee573e57b5b182d8e5f5db63240f.tar.gz | |
Implement PEP 3115 -- new metaclass syntax and semantics.
The compiler package hasn't been updated yet; test_compiler.py fails.
Otherwise all tests seem to be passing now.  There are no occurrences
of __metaclass__ left in the standard library.
Docs have not been updated.
Diffstat (limited to 'Python')
| -rw-r--r-- | Python/Python-ast.c | 28 | ||||
| -rw-r--r-- | Python/ast.c | 59 | ||||
| -rw-r--r-- | Python/bltinmodule.c | 109 | ||||
| -rw-r--r-- | Python/ceval.c | 89 | ||||
| -rw-r--r-- | Python/compile.c | 174 | ||||
| -rw-r--r-- | Python/graminit.c | 2 | ||||
| -rw-r--r-- | Python/import.c | 3 | ||||
| -rw-r--r-- | Python/symtable.c | 5 | 
8 files changed, 303 insertions, 166 deletions
diff --git a/Python/Python-ast.c b/Python/Python-ast.c index c024a62776..76c86c17e1 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -49,6 +49,9 @@ static PyTypeObject *ClassDef_type;  static char *ClassDef_fields[]={          "name",          "bases", +        "keywords", +        "starargs", +        "kwargs",          "body",  };  static PyTypeObject *Return_type; @@ -477,7 +480,7 @@ static int init_types(void)          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 @@ FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq *  }  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 @@ ClassDef(identifier name, asdl_seq * bases, asdl_seq * body, int lineno, int          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 @@ ast2obj_stmt(void* _o)                  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) diff --git a/Python/ast.c b/Python/ast.c index c8357b1b85..d4c89677f7 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -2092,28 +2092,6 @@ ast_for_testlist_gexp(struct compiling *c, const node* n)      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 @@ ast_for_with_stmt(struct compiling *c, const node *n)  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 @@ ast_for_classdef(struct compiling *c, const node *n)              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 diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 5d87744900..4aa9c6290d 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -31,6 +31,113 @@ static PyObject *filterunicode(PyObject *, PyObject *);  static PyObject *filtertuple (PyObject *, PyObject *);  static PyObject * +builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds) +{ +	PyObject *func, *name, *bases, *mkw, *meta, *prep, *ns, *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) { +		meta = NULL; +                mkw = NULL; +        } +	else { +		mkw = PyDict_Copy(kwds); /* Don't modify kwds passed in! */ +		if (mkw == NULL) { +			Py_DECREF(bases); +			return NULL; +		} +		meta = PyDict_GetItemString(mkw, "metaclass"); +		if (meta != NULL) { +			Py_INCREF(meta); +			if (PyDict_DelItemString(mkw, "metaclass") < 0) { +				Py_DECREF(meta); +				Py_DECREF(mkw); +				Py_DECREF(bases); +				return NULL; +			} +		} +	} +	if (meta == NULL) { +		if (PyTuple_GET_SIZE(bases) == 0) +			meta = (PyObject *) (&PyType_Type); +		else { +			PyObject *base0 = PyTuple_GET_ITEM(bases, 0); +			meta = (PyObject *) (base0->ob_type); +		} +		Py_INCREF(meta); +	} +	prep = PyObject_GetAttrString(meta, "__prepare__"); +	if (prep == NULL) { +		PyErr_Clear(); +		ns = PyDict_New(); +	} +	else { +		PyObject *pargs = Py_BuildValue("OO", name, bases); +		if (pargs == NULL) { +			Py_DECREF(prep); +			Py_DECREF(meta); +			Py_XDECREF(mkw); +			Py_DECREF(bases); +			return NULL; +		} +		ns = PyEval_CallObjectWithKeywords(prep, pargs, mkw); +		Py_DECREF(pargs); +		Py_DECREF(prep); +		if (ns == NULL) { +			Py_DECREF(meta); +			Py_XDECREF(mkw); +			Py_DECREF(bases); +			return NULL; +		} +	} +	res = PyObject_CallFunctionObjArgs(func, ns, NULL); +	if (res != NULL) { +		PyObject *margs; +		Py_DECREF(res); +		res = NULL; +		margs = Py_BuildValue("OOO", name, bases, ns); +		if (margs != NULL) { +			res = PyEval_CallObjectWithKeywords(meta, margs, mkw); +			Py_DECREF(margs); +		} +	} +	Py_DECREF(ns); +	Py_DECREF(meta); +	Py_XDECREF(mkw); +	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 +2210,8 @@ NOTE: This is implemented using itertools.izip().");  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}, diff --git a/Python/ceval.c b/Python/ceval.c index 5cad632c6d..5a3fc59295 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -117,7 +117,6 @@ static int assign_slice(PyObject *, PyObject *,  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 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)  			}  			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 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)  			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 @@ import_all_from(PyObject *locals, PyObject *v)  	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)  { diff --git a/Python/compile.c b/Python/compile.c index 1e4dddf891..4c22441026 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -176,6 +176,11 @@ static int inplace_binop(struct compiler *, operator_ty);  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 @@ opcode_stack_effect(int opcode, int oparg)  		case PRINT_EXPR:  			return -1; +		case LOAD_BUILD_CLASS: +			return 1;  		case INPLACE_LSHIFT:  		case INPLACE_RSHIFT:  		case INPLACE_AND: @@ -744,8 +751,8 @@ opcode_stack_effect(int opcode, int oparg)  			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 @@ opcode_stack_effect(int opcode, int oparg)  			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 @@ compiler_function(struct compiler *c, stmt_ty s)  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: +	     <name> = __build_class__(<func>, <name>, *<bases>, **<keywords>) +	   where: +	     <func> is a function/closure created from the class body +	     <name> is the class name +             <bases> is the positional arguments and *varargs argument +	     <keywords> 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; -	} -	ADDOP_IN_SCOPE(c, LOAD_LOCALS); -	ADDOP_IN_SCOPE(c, RETURN_VALUE); -	co = assemble(c, 1); +	/* 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); +	} +	/* 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 <name> */  	if (!compiler_nameop(c, s->v.ClassDef.name, Store))  		return 0;  	return 1; @@ -2613,21 +2671,37 @@ compiler_compare(struct compiler *c, expr_ty e)  static int  compiler_call(struct compiler *c, expr_ty e)  { -	int n, code = 0; -  	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; -	} -	if (e->v.Call.starargs) { -		VISIT(c, expr, e->v.Call.starargs); +	return compiler_call_helper(c, 0, +				    e->v.Call.args, +				    e->v.Call.keywords, +				    e->v.Call.starargs, +				    e->v.Call.kwargs); +} + +/* 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 (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) { diff --git a/Python/graminit.c b/Python/graminit.c index 5c7fb6a5e2..12872196a1 100644 --- a/Python/graminit.c +++ b/Python/graminit.c @@ -1635,7 +1635,7 @@ static arc arcs_76_2[2] = {  	{23, 4},  };  static arc arcs_76_3[2] = { -	{9, 5}, +	{14, 5},  	{15, 6},  };  static arc arcs_76_4[1] = { diff --git a/Python/import.c b/Python/import.c index fae60cf1b2..33953c7e54 100644 --- a/Python/import.c +++ b/Python/import.c @@ -72,9 +72,10 @@ extern time_t PyOS_GetLastModificationTime(char *, FILE *);  		      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 diff --git a/Python/symtable.c b/Python/symtable.c index 5bac2a2c9e..e9c9391580 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -983,6 +983,11 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)  		if (!symtable_add_def(st, s->v.ClassDef.name, DEF_LOCAL))  			return 0;  		VISIT_SEQ(st, expr, s->v.ClassDef.bases); +		VISIT_SEQ(st, keyword, 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;  | 
