From: Guido van Rossum Date: Mon, 7 Oct 2002 18:08:27 +0000 (+0000) Subject: Backport, at the reqest of Kevin Jacobs: X-Git-Tag: v2.2.2b1~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0df0b42f7c4df9f720731dc4ce4962f7f4f6d409;p=thirdparty%2FPython%2Fcpython.git Backport, at the reqest of Kevin Jacobs: - 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] XXX This is arguably a semantic change, but it's hard to imagine a reason for wanting to depend on the old behavior. If problems with this are reported within a week of the release of 2.2.2 beta 1, we may revert this change. --- diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 84f3da965a77..74e33499d093 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -3017,6 +3017,27 @@ def subtype_resurrection(): # it as a leak. del C.__del__ +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() @@ -3078,6 +3099,7 @@ def test_main(): imulbug() copy_setstate() subtype_resurrection() + funnynew() if verbose: print "All OK" if __name__ == "__main__": diff --git a/Misc/NEWS b/Misc/NEWS index 6e849da1b9b9..8ab75cc49630 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -1,9 +1,16 @@ -What's New in Python 2.2.2? -Release date: dd-mmm-2002 -=========================== +What's New in Python 2.2.2b1? +Release date: 7-Oct-2002 +============================= 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] (This is arguably a semantic change, + but it's hard to imagine a reason for wanting to depend on the old + behavior. If problems with this are reported within a week of the + release of 2.2.2 beta 1, we may revert this change.) + - u'%c' will now raise a ValueError in case the argument is an integer outside the valid range of Unicode code point ordinals. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index c9c29fe6f300..d134e0c407b1 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -189,6 +189,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 (PyType_HasFeature(type, Py_TPFLAGS_HAVE_CLASS) && type->tp_init != NULL &&