mirror of
https://github.com/python/cpython.git
synced 2025-09-09 02:11:51 +00:00
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.
This commit is contained in:
parent
ef17c16b36
commit
52cc1d838f
25 changed files with 604 additions and 237 deletions
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue