Commit 77eb0f6f authored by Stefan Behnel's avatar Stefan Behnel

support non-types as Py2 metaclasses

parent 455e0357
...@@ -868,35 +868,24 @@ static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObj ...@@ -868,35 +868,24 @@ static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObj
PyObject *dict, PyObject *mkw, PyObject *dict, PyObject *mkw,
int calculate_metaclass, int allow_py2_metaclass) { int calculate_metaclass, int allow_py2_metaclass) {
PyObject *result, *margs; PyObject *result, *margs;
PyObject *py2_metaclass = NULL; PyObject *owned_metaclass = NULL;
if (allow_py2_metaclass) { if (allow_py2_metaclass) {
/* honour Python2 __metaclass__ for backward compatibility */ /* honour Python2 __metaclass__ for backward compatibility */
py2_metaclass = PyObject_GetItem(dict, PYIDENT("__metaclass__")); owned_metaclass = PyObject_GetItem(dict, PYIDENT("__metaclass__"));
if (py2_metaclass) { if (owned_metaclass) {
if (likely(PyType_Check(py2_metaclass))) { metaclass = owned_metaclass;
metaclass = py2_metaclass;
calculate_metaclass = 1;
} else {
/* py2_metaclass != NULL => calculate_metaclass != 0 */
Py_DECREF(py2_metaclass);
py2_metaclass = NULL;
}
} else if (likely(PyErr_ExceptionMatches(PyExc_KeyError))) { } else if (likely(PyErr_ExceptionMatches(PyExc_KeyError))) {
PyErr_Clear(); PyErr_Clear();
} else { } else {
return NULL; return NULL;
} }
} }
if (calculate_metaclass) { if (calculate_metaclass && (!metaclass || PyType_Check(metaclass))) {
if (py2_metaclass || PyType_Check(metaclass)) { metaclass = __Pyx_CalculateMetaclass((PyTypeObject*) metaclass, bases);
metaclass = __Pyx_CalculateMetaclass((PyTypeObject*) metaclass, bases); Py_XDECREF(owned_metaclass);
Py_XDECREF(py2_metaclass); if (unlikely(!metaclass))
if (unlikely(!metaclass)) return NULL;
return NULL; owned_metaclass = metaclass;
} else {
Py_XDECREF(py2_metaclass);
calculate_metaclass = 0;
}
} }
margs = PyTuple_Pack(3, name, bases, dict); margs = PyTuple_Pack(3, name, bases, dict);
if (unlikely(!margs)) { if (unlikely(!margs)) {
...@@ -905,9 +894,7 @@ static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObj ...@@ -905,9 +894,7 @@ static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObj
result = PyObject_Call(metaclass, margs, mkw); result = PyObject_Call(metaclass, margs, mkw);
Py_DECREF(margs); Py_DECREF(margs);
} }
if (calculate_metaclass) { Py_XDECREF(owned_metaclass);
Py_DECREF(metaclass);
}
return result; return result;
} }
......
...@@ -15,6 +15,26 @@ class Foo(object): ...@@ -15,6 +15,26 @@ class Foo(object):
""" """
__metaclass__ = Base __metaclass__ = Base
def non_type_metaclass(name, bases, namespace):
namespace['BASES'] = [b.__name__ for b in bases]
namespace['NAME'] = name
return type(name, bases, namespace)
class FunctionAsPy2Metaclass(object):
"""
>>> obj = FunctionAsPy2Metaclass()
>>> obj.NAME
'FunctionAsPy2Metaclass'
>>> obj.BASES
['object']
>>> obj.x
1
"""
__metaclass__ = non_type_metaclass
x = 1
class ODict(dict): class ODict(dict):
def __init__(self): def __init__(self):
dict.__init__(self) dict.__init__(self)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment