- Changed new-style class instantiation so that when C's __new__

method returns something that's not a C instance, its __init__ is
  not called.  [SF bug #537450]
This commit is contained in:
Guido van Rossum 2002-04-06 01:05:01 +00:00
parent 181e41ad40
commit 8ace1ab53a
3 changed files with 30 additions and 0 deletions

View File

@ -2897,6 +2897,27 @@ def dictproxyiteritems():
keys.sort()
vereq(keys, ['__dict__', '__doc__', '__module__', '__weakref__', 'meth'])
def funnynew():
if verbose: print "Testing __new__ returning something unexpected..."
class C(object):
def __new__(cls, arg):
if isinstance(arg, str): return [1, 2, 3]
elif isinstance(arg, int): return object.__new__(D)
else: return object.__new__(cls)
class D(C):
def __init__(self, arg):
self.foo = arg
vereq(C("1"), [1, 2, 3])
vereq(D("1"), [1, 2, 3])
d = D(None)
veris(d.foo, None)
d = C(1)
vereq(isinstance(d, D), True)
vereq(d.foo, 1)
d = D(1)
vereq(isinstance(d, D), True)
vereq(d.foo, 1)
def test_main():
class_docstrings()
lists()
@ -2959,6 +2980,7 @@ def test_main():
dictproxyitervalues()
dictproxyiteritems()
pickleslots()
funnynew()
if verbose: print "All OK"
if __name__ == "__main__":

View File

@ -6,6 +6,10 @@ Type/class unification and new-style classes
Core and builtins
- Changed new-style class instantiation so that when C's __new__
method returns something that's not a C instance, its __init__ is
not called. [SF bug #537450]
- Fixed super() to work correctly with class methods. [SF bug #535444]
- A new built-in type, bool, has been added, as well as built-in

View File

@ -169,6 +169,10 @@ type_call(PyTypeObject *type, PyObject *args, PyObject *kwds)
(kwds == NULL ||
(PyDict_Check(kwds) && PyDict_Size(kwds) == 0)))
return obj;
/* If the returned object is not an instance of type,
it won't be initialized. */
if (!PyType_IsSubtype(obj->ob_type, type))
return obj;
type = obj->ob_type;
if (type->tp_init != NULL &&
type->tp_init(obj, args, kwds) < 0) {