diff options
author | Guido van Rossum <guido@python.org> | 2001-10-18 15:49:21 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2001-10-18 15:49:21 (GMT) |
commit | f76de62f7d48a25d5f67357ae7b2f487904a5fcc (patch) | |
tree | fbdeb2efbe6d67caa25a5cb03163af7b573f29b5 | |
parent | b7da67a873595f022c890783856f7ee764a00c3a (diff) | |
download | cpython-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.py | 12 | ||||
-rw-r--r-- | Misc/ACKS | 1 | ||||
-rw-r--r-- | Objects/typeobject.c | 7 |
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 = [] @@ -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) { |