summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2007-03-23 18:53:03 (GMT)
committerGuido van Rossum <guido@python.org>2007-03-23 18:53:03 (GMT)
commitf102e24bd34442026f4200a298a8b08d1deb3616 (patch)
tree8615ed95b550b4c4493721fc9136fd01ca0b5da7
parent0af338859b86880cdfe0fe5b3abeea8acace33eb (diff)
downloadcpython-f102e24bd34442026f4200a298a8b08d1deb3616.zip
cpython-f102e24bd34442026f4200a298a8b08d1deb3616.tar.gz
cpython-f102e24bd34442026f4200a298a8b08d1deb3616.tar.bz2
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__().
-rw-r--r--Lib/string.py4
-rw-r--r--Objects/typeobject.c35
2 files changed, 35 insertions, 4 deletions
diff --git a/Lib/string.py b/Lib/string.py
index d4d13b2..921bd8b 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 c1e3ff3..0ce7f82 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 */