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.
This commit is contained in:
Guido van Rossum 2001-10-18 15:49:21 +00:00
parent b7da67a873
commit f76de62f7d
3 changed files with 20 additions and 0 deletions

View File

@ -716,6 +716,18 @@ def _get_x(self):
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 = []

View File

@ -337,6 +337,7 @@ Sean Reifschneider
Michael P. Reilly
Bernhard Reiter
Steven Reiz
Roeland Rengelink
Jan Pieter Riegel
Armin Rigo
Nicholas Riley

View File

@ -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) {