summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2001-10-18 15:49:21 (GMT)
committerGuido van Rossum <guido@python.org>2001-10-18 15:49:21 (GMT)
commitf76de62f7d48a25d5f67357ae7b2f487904a5fcc (patch)
treefbdeb2efbe6d67caa25a5cb03163af7b573f29b5
parentb7da67a873595f022c890783856f7ee764a00c3a (diff)
downloadcpython-f76de62f7d48a25d5f67357ae7b2f487904a5fcc.zip
cpython-f76de62f7d48a25d5f67357ae7b2f487904a5fcc.tar.gz
cpython-f76de62f7d48a25d5f67357ae7b2f487904a5fcc.tar.bz2
Fix SF bug #472234: type(obj) calls type->tp_init (Roeland Rengelink)
The fix is a band-aid: type_call() now makes the same exception for a single-argument call to type() as type_new() was already making.
-rw-r--r--Lib/test/test_descr.py12
-rw-r--r--Misc/ACKS1
-rw-r--r--Objects/typeobject.c7
3 files changed, 20 insertions, 0 deletions
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index c9235c8..962c1cc 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -716,6 +716,18 @@ def metaclass():
return "D" + self.__super._get_x()
vereq(D().x, "DCBA")
+ # Make sure type(x) doesn't call x.__class__.__init__
+ class T(type):
+ counter = 0
+ def __init__(self, *args):
+ T.counter += 1
+ class C:
+ __metaclass__ = T
+ vereq(T.counter, 1)
+ a = C()
+ vereq(type(a), C)
+ vereq(T.counter, 1)
+
def pymods():
if verbose: print "Testing Python subclass of module..."
log = []
diff --git a/Misc/ACKS b/Misc/ACKS
index 0ae72c3..e7400e9 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -337,6 +337,7 @@ Sean Reifschneider
Michael P. Reilly
Bernhard Reiter
Steven Reiz
+Roeland Rengelink
Jan Pieter Riegel
Armin Rigo
Nicholas Riley
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index c37e54f..66eecec 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -147,6 +147,13 @@ type_call(PyTypeObject *type, PyObject *args, PyObject *kwds)
obj = type->tp_new(type, args, kwds);
if (obj != NULL) {
+ /* Ugly exception: when the call was type(something),
+ don't call tp_init on the result. */
+ if (type == &PyType_Type &&
+ PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 &&
+ (kwds == NULL ||
+ (PyDict_Check(kwds) && PyDict_Size(kwds) == 0)))
+ return obj;
type = obj->ob_type;
if (type->tp_init != NULL &&
type->tp_init(obj, args, kwds) < 0) {