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() return "D" + self.__super._get_x()
vereq(D().x, "DCBA") 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(): def pymods():
if verbose: print "Testing Python subclass of module..." if verbose: print "Testing Python subclass of module..."
log = [] log = []

View File

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

View File

@ -147,6 +147,13 @@ type_call(PyTypeObject *type, PyObject *args, PyObject *kwds)
obj = type->tp_new(type, args, kwds); obj = type->tp_new(type, args, kwds);
if (obj != NULL) { 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; type = obj->ob_type;
if (type->tp_init != NULL && if (type->tp_init != NULL &&
type->tp_init(obj, args, kwds) < 0) { type->tp_init(obj, args, kwds) < 0) {