From f102e24bd34442026f4200a298a8b08d1deb3616 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Fri, 23 Mar 2007 18:53:03 +0000 Subject: [PATCH] Add a type.__init__() method that enforces the same signature as type.__new__(), and then calls object.__init__(cls), just to be anal. This allows us to restore the code in string.py's _TemplateMetaclass that called super(...).__init__(name, bases, dct), which I commented out yesterday since it broke due to the stricter argument checking added to object.__init__(). --- Lib/string.py | 4 +--- Objects/typeobject.c | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/Lib/string.py b/Lib/string.py index d4d13b22726..921bd8b1d01 100644 --- a/Lib/string.py +++ b/Lib/string.py @@ -108,9 +108,7 @@ class _TemplateMetaclass(type): """ def __init__(cls, name, bases, dct): - # A super call makes no sense since type() doesn't define __init__(). - # (Or does it? And should type.__init__() accept three args?) - # super(_TemplateMetaclass, cls).__init__(name, bases, dct) + super(_TemplateMetaclass, cls).__init__(name, bases, dct) if 'pattern' in dct: pattern = cls.pattern else: diff --git a/Objects/typeobject.c b/Objects/typeobject.c index c1e3ff3b56d..0ce7f828614 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1684,6 +1684,39 @@ _unicode_to_string(PyObject *slots, Py_ssize_t nslots) } #endif +/* Forward */ +static int +object_init(PyObject *self, PyObject *args, PyObject *kwds); + +static int +type_init(PyObject *cls, PyObject *args, PyObject *kwds) +{ + int res; + + assert(args != NULL && PyTuple_Check(args)); + assert(kwds == NULL || PyDict_Check(kwds)); + + if (kwds != NULL && PyDict_Check(kwds) && PyDict_Size(kwds) != 0) { + PyErr_SetString(PyExc_TypeError, + "type.__init__() takes no keyword arguments"); + return -1; + } + + if (args != NULL && PyTuple_Check(args) && + (PyTuple_GET_SIZE(args) != 1 && PyTuple_GET_SIZE(args) != 3)) { + PyErr_SetString(PyExc_TypeError, + "type.__init__() takes 1 or 3 arguments"); + return -1; + } + + /* Call object.__init__(self) now. */ + /* XXX Could call super(type, cls).__init__() but what's the point? */ + args = PyTuple_GetSlice(args, 0, 0); + res = object_init(cls, args, NULL); + Py_DECREF(args); + return res; +} + static PyObject * type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) { @@ -2381,7 +2414,7 @@ PyTypeObject PyType_Type = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ offsetof(PyTypeObject, tp_dict), /* tp_dictoffset */ - 0, /* tp_init */ + type_init, /* tp_init */ 0, /* tp_alloc */ type_new, /* tp_new */ PyObject_GC_Del, /* tp_free */