mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
- 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:
parent
181e41ad40
commit
8ace1ab53a
3 changed files with 30 additions and 0 deletions
|
@ -2897,6 +2897,27 @@ def dictproxyiteritems():
|
||||||
keys.sort()
|
keys.sort()
|
||||||
vereq(keys, ['__dict__', '__doc__', '__module__', '__weakref__', 'meth'])
|
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():
|
def test_main():
|
||||||
class_docstrings()
|
class_docstrings()
|
||||||
lists()
|
lists()
|
||||||
|
@ -2959,6 +2980,7 @@ def test_main():
|
||||||
dictproxyitervalues()
|
dictproxyitervalues()
|
||||||
dictproxyiteritems()
|
dictproxyiteritems()
|
||||||
pickleslots()
|
pickleslots()
|
||||||
|
funnynew()
|
||||||
if verbose: print "All OK"
|
if verbose: print "All OK"
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -6,6 +6,10 @@ Type/class unification and new-style classes
|
||||||
|
|
||||||
Core and builtins
|
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]
|
- 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
|
- A new built-in type, bool, has been added, as well as built-in
|
||||||
|
|
|
@ -169,6 +169,10 @@ type_call(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
(kwds == NULL ||
|
(kwds == NULL ||
|
||||||
(PyDict_Check(kwds) && PyDict_Size(kwds) == 0)))
|
(PyDict_Check(kwds) && PyDict_Size(kwds) == 0)))
|
||||||
return obj;
|
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;
|
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) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue