cpython: 9605c558ab58 (original) (raw)
--- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -7,6 +7,7 @@ import pickle import sys import types import unittest +import warnings import weakref from copy import deepcopy @@ -1661,6 +1662,75 @@ order (MRO) for bases """ self.assertEqual(b.foo, 3) self.assertEqual(b.class, D)
- def test_bad_new(self):
self.assertRaises(TypeError, object.__new__)[](#l1.16)
self.assertRaises(TypeError, object.__new__, '')[](#l1.17)
self.assertRaises(TypeError, list.__new__, object)[](#l1.18)
self.assertRaises(TypeError, object.__new__, list)[](#l1.19)
class C(object):[](#l1.20)
__new__ = list.__new__[](#l1.21)
self.assertRaises(TypeError, C)[](#l1.22)
class C(list):[](#l1.23)
__new__ = object.__new__[](#l1.24)
self.assertRaises(TypeError, C)[](#l1.25)
- def test_object_new(self):
class A(object):[](#l1.28)
pass[](#l1.29)
object.__new__(A)[](#l1.30)
self.assertRaises(TypeError, object.__new__, A, 5)[](#l1.31)
object.__init__(A())[](#l1.32)
self.assertRaises(TypeError, object.__init__, A(), 5)[](#l1.33)
class A(object):[](#l1.35)
def __init__(self, foo):[](#l1.36)
self.foo = foo[](#l1.37)
object.__new__(A)[](#l1.38)
object.__new__(A, 5)[](#l1.39)
object.__init__(A(3))[](#l1.40)
self.assertRaises(TypeError, object.__init__, A(3), 5)[](#l1.41)
class A(object):[](#l1.43)
def __new__(cls, foo):[](#l1.44)
return object.__new__(cls)[](#l1.45)
object.__new__(A)[](#l1.46)
self.assertRaises(TypeError, object.__new__, A, 5)[](#l1.47)
object.__init__(A(3))[](#l1.48)
object.__init__(A(3), 5)[](#l1.49)
class A(object):[](#l1.51)
def __new__(cls, foo):[](#l1.52)
return object.__new__(cls)[](#l1.53)
def __init__(self, foo):[](#l1.54)
self.foo = foo[](#l1.55)
object.__new__(A)[](#l1.56)
self.assertRaises(TypeError, object.__new__, A, 5)[](#l1.57)
object.__init__(A(3))[](#l1.58)
self.assertRaises(TypeError, object.__init__, A(3), 5)[](#l1.59)
- def test_restored_object_new(self):
class A(object):[](#l1.62)
def __new__(cls, *args, **kwargs):[](#l1.63)
raise AssertionError[](#l1.64)
self.assertRaises(AssertionError, A)[](#l1.65)
class B(A):[](#l1.66)
__new__ = object.__new__[](#l1.67)
def __init__(self, foo):[](#l1.68)
self.foo = foo[](#l1.69)
with warnings.catch_warnings():[](#l1.70)
warnings.simplefilter('error', DeprecationWarning)[](#l1.71)
b = B(3)[](#l1.72)
self.assertEqual(b.foo, 3)[](#l1.73)
self.assertEqual(b.__class__, B)[](#l1.74)
del B.__new__[](#l1.75)
self.assertRaises(AssertionError, B)[](#l1.76)
del A.__new__[](#l1.77)
with warnings.catch_warnings():[](#l1.78)
warnings.simplefilter('error', DeprecationWarning)[](#l1.79)
b = B(3)[](#l1.80)
self.assertEqual(b.foo, 3)[](#l1.81)
self.assertEqual(b.__class__, B)[](#l1.82)
+ def test_altmro(self): # Testing mro() and overriding it... class A(object): @@ -3522,6 +3592,24 @@ order (MRO) for bases """ self.assertIsInstance(d, D) self.assertEqual(d.foo, 1)
class C(object):[](#l1.91)
@staticmethod[](#l1.92)
def __new__(*args):[](#l1.93)
return args[](#l1.94)
self.assertEqual(C(1, 2), (C, 1, 2))[](#l1.95)
class D(C):[](#l1.96)
pass[](#l1.97)
self.assertEqual(D(1, 2), (D, 1, 2))[](#l1.98)
class C(object):[](#l1.100)
@classmethod[](#l1.101)
def __new__(*args):[](#l1.102)
return args[](#l1.103)
self.assertEqual(C(1, 2), (C, C, 1, 2))[](#l1.104)
class D(C):[](#l1.105)
pass[](#l1.106)
self.assertEqual(D(1, 2), (D, D, 1, 2))[](#l1.107)
+ def test_imul_bug(self): # Testing for imul problems... # SF bug 544647
--- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ What's New in Python 3.7.0 alpha 1 Core and Builtins ----------------- +- Issue #5322: Fixed setting new to a PyCFunction inside Python code.
- Issue #23722: Rather than silently producing a class that doesn't support
zero-argument
super()
in methods, failing to pass the new__classcell__
namespace entry up totype.__new__
now results in a
--- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -6878,7 +6878,34 @@ update_one_slot(PyTypeObject *type, slot sanity checks and constructing a new argument list. Cut all that nonsense short -- this speeds up instance creation tremendously. */
specific = (void *)type->tp_new;[](#l3.7)
PyObject *self = PyCFunction_GET_SELF(descr);[](#l3.8)
if (!self || !PyType_Check(self)) {[](#l3.9)
/* This should never happen because[](#l3.10)
tp_new_wrapper expects a type for self.[](#l3.11)
Use slot_tp_new which will call[](#l3.12)
tp_new_wrapper which will raise an[](#l3.13)
exception. */[](#l3.14)
specific = (void *)slot_tp_new;[](#l3.15)
}[](#l3.16)
else {[](#l3.17)
PyTypeObject *staticbase;[](#l3.18)
specific = ((PyTypeObject *)self)->tp_new;[](#l3.19)
/* Check that the user does not do anything[](#l3.20)
silly and unsafe like object.__new__(dict).[](#l3.21)
To do this, we check that the most derived[](#l3.22)
base that's not a heap type is this type. */[](#l3.23)
staticbase = type->tp_base;[](#l3.24)
while (staticbase &&[](#l3.25)
(staticbase->tp_flags & Py_TPFLAGS_HEAPTYPE))[](#l3.26)
staticbase = staticbase->tp_base;[](#l3.27)
if (staticbase &&[](#l3.28)
staticbase->tp_new != specific)[](#l3.29)
/* Seems to be unsafe, better use[](#l3.30)
slot_tp_new which will call[](#l3.31)
tp_new_wrapper which will raise an[](#l3.32)
exception if it is unsafe. */[](#l3.33)
specific = (void *)slot_tp_new;[](#l3.34)
}[](#l3.35) /* XXX I'm not 100% sure that there isn't a hole[](#l3.36) in this reasoning that requires additional[](#l3.37) sanity checks. I'll buy the first person to[](#l3.38)