]> granicus.if.org Git - python/commitdiff
- Changed new-style class instantiation so that when C's __new__
authorGuido van Rossum <guido@python.org>
Sat, 6 Apr 2002 01:05:01 +0000 (01:05 +0000)
committerGuido van Rossum <guido@python.org>
Sat, 6 Apr 2002 01:05:01 +0000 (01:05 +0000)
  method returns something that's not a C instance, its __init__ is
  not called.  [SF bug #537450]

Lib/test/test_descr.py
Misc/NEWS
Objects/typeobject.c

index 8d8c276179aa68db79a3a839239654436e19d95b..ab5595287c48d3d135745ed730df9bffc6bd901c 100644 (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__":
index 8c424604c54cba560501f5731ea3239e90635975..4923dce9617de98c6b9b92f6e9525962fbfe1a8d 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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
index 71d22f3534d1a25a1caa9ed5a683f78ae8fb765f..51ed4301fde2c54e30779ab09d392af2c80e399e 100644 (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) {