mirror of https://github.com/python/cpython
Bug #1486663: don't reject keyword arguments for subclasses of builtin
types.
This commit is contained in:
parent
aef4c6bc00
commit
b84c13792d
|
@ -12,6 +12,10 @@ from cPickle import loads, dumps
|
||||||
class ArraySubclass(array.array):
|
class ArraySubclass(array.array):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class ArraySubclassWithKwargs(array.array):
|
||||||
|
def __init__(self, typecode, newarg=None):
|
||||||
|
array.array.__init__(typecode)
|
||||||
|
|
||||||
tests = [] # list to accumulate all tests
|
tests = [] # list to accumulate all tests
|
||||||
typecodes = "cubBhHiIlLfd"
|
typecodes = "cubBhHiIlLfd"
|
||||||
|
|
||||||
|
@ -683,6 +687,9 @@ class BaseTest(unittest.TestCase):
|
||||||
b = array.array('B', range(64))
|
b = array.array('B', range(64))
|
||||||
self.assertEqual(rc, sys.getrefcount(10))
|
self.assertEqual(rc, sys.getrefcount(10))
|
||||||
|
|
||||||
|
def test_subclass_with_kwargs(self):
|
||||||
|
# SF bug #1486663 -- this used to erroneously raise a TypeError
|
||||||
|
ArraySubclassWithKwargs('b', newarg=1)
|
||||||
|
|
||||||
|
|
||||||
class StringTest(BaseTest):
|
class StringTest(BaseTest):
|
||||||
|
|
|
@ -486,6 +486,16 @@ class TestSubclass(unittest.TestCase):
|
||||||
d1 == d2 # not clear if this is supposed to be True or False,
|
d1 == d2 # not clear if this is supposed to be True or False,
|
||||||
# but it used to give a SystemError
|
# but it used to give a SystemError
|
||||||
|
|
||||||
|
|
||||||
|
class SubclassWithKwargs(deque):
|
||||||
|
def __init__(self, newarg=1):
|
||||||
|
deque.__init__(self)
|
||||||
|
|
||||||
|
class TestSubclassWithKwargs(unittest.TestCase):
|
||||||
|
def test_subclass_with_kwargs(self):
|
||||||
|
# SF bug #1486663 -- this used to erroneously raise a TypeError
|
||||||
|
SubclassWithKwargs(newarg=1)
|
||||||
|
|
||||||
#==============================================================================
|
#==============================================================================
|
||||||
|
|
||||||
libreftest = """
|
libreftest = """
|
||||||
|
@ -599,6 +609,7 @@ def test_main(verbose=None):
|
||||||
TestBasic,
|
TestBasic,
|
||||||
TestVariousIteratorArgs,
|
TestVariousIteratorArgs,
|
||||||
TestSubclass,
|
TestSubclass,
|
||||||
|
TestSubclassWithKwargs,
|
||||||
)
|
)
|
||||||
|
|
||||||
test_support.run_unittest(*test_classes)
|
test_support.run_unittest(*test_classes)
|
||||||
|
|
|
@ -740,6 +740,21 @@ class RegressionTests(unittest.TestCase):
|
||||||
self.assertRaises(AssertionError, list, cycle(gen1()))
|
self.assertRaises(AssertionError, list, cycle(gen1()))
|
||||||
self.assertEqual(hist, [0,1])
|
self.assertEqual(hist, [0,1])
|
||||||
|
|
||||||
|
class SubclassWithKwargsTest(unittest.TestCase):
|
||||||
|
def test_keywords_in_subclass(self):
|
||||||
|
# count is not subclassable...
|
||||||
|
for cls in (repeat, izip, ifilter, ifilterfalse, chain, imap,
|
||||||
|
starmap, islice, takewhile, dropwhile, cycle):
|
||||||
|
class Subclass(cls):
|
||||||
|
def __init__(self, newarg=None, *args):
|
||||||
|
cls.__init__(self, *args)
|
||||||
|
try:
|
||||||
|
Subclass(newarg=1)
|
||||||
|
except TypeError, err:
|
||||||
|
# we expect type errors because of wrong argument count
|
||||||
|
self.failIf("does not take keyword arguments" in err.args[0])
|
||||||
|
|
||||||
|
|
||||||
libreftest = """ Doctest for examples in the library reference: libitertools.tex
|
libreftest = """ Doctest for examples in the library reference: libitertools.tex
|
||||||
|
|
||||||
|
|
||||||
|
@ -934,7 +949,8 @@ __test__ = {'libreftest' : libreftest}
|
||||||
|
|
||||||
def test_main(verbose=None):
|
def test_main(verbose=None):
|
||||||
test_classes = (TestBasicOps, TestVariousIteratorArgs, TestGC,
|
test_classes = (TestBasicOps, TestVariousIteratorArgs, TestGC,
|
||||||
RegressionTests, LengthTransparency)
|
RegressionTests, LengthTransparency,
|
||||||
|
SubclassWithKwargsTest)
|
||||||
test_support.run_unittest(*test_classes)
|
test_support.run_unittest(*test_classes)
|
||||||
|
|
||||||
# verify reference counting
|
# verify reference counting
|
||||||
|
|
|
@ -515,6 +515,14 @@ class TestModule(unittest.TestCase):
|
||||||
# tests validity but not completeness of the __all__ list
|
# tests validity but not completeness of the __all__ list
|
||||||
self.failUnless(set(random.__all__) <= set(dir(random)))
|
self.failUnless(set(random.__all__) <= set(dir(random)))
|
||||||
|
|
||||||
|
def test_random_subclass_with_kwargs(self):
|
||||||
|
# SF bug #1486663 -- this used to erroneously raise a TypeError
|
||||||
|
class Subclass(random.Random):
|
||||||
|
def __init__(self, newarg=None):
|
||||||
|
random.Random.__init__(self)
|
||||||
|
Subclass(newarg=1)
|
||||||
|
|
||||||
|
|
||||||
def test_main(verbose=None):
|
def test_main(verbose=None):
|
||||||
testclasses = [WichmannHill_TestBasicOps,
|
testclasses = [WichmannHill_TestBasicOps,
|
||||||
MersenneTwister_TestBasicOps,
|
MersenneTwister_TestBasicOps,
|
||||||
|
|
|
@ -313,6 +313,9 @@ Library
|
||||||
Extension Modules
|
Extension Modules
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Bug #1486663: don't reject keyword arguments for subclasses of builtin
|
||||||
|
types.
|
||||||
|
|
||||||
- Patch #1610575: The struct module now supports the 't' code, for
|
- Patch #1610575: The struct module now supports the 't' code, for
|
||||||
C99 _Bool.
|
C99 _Bool.
|
||||||
|
|
||||||
|
|
|
@ -481,7 +481,7 @@ random_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
RandomObject *self;
|
RandomObject *self;
|
||||||
PyObject *tmp;
|
PyObject *tmp;
|
||||||
|
|
||||||
if (!_PyArg_NoKeywords("Random()", kwds))
|
if (type == &Random_Type && !_PyArg_NoKeywords("Random()", kwds))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
self = (RandomObject *)type->tp_alloc(type, 0);
|
self = (RandomObject *)type->tp_alloc(type, 0);
|
||||||
|
|
|
@ -1797,7 +1797,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
PyObject *initial = NULL, *it = NULL;
|
PyObject *initial = NULL, *it = NULL;
|
||||||
struct arraydescr *descr;
|
struct arraydescr *descr;
|
||||||
|
|
||||||
if (!_PyArg_NoKeywords("array.array()", kwds))
|
if (type == &Arraytype && !_PyArg_NoKeywords("array.array()", kwds))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "c|O:array", &c, &initial))
|
if (!PyArg_ParseTuple(args, "c|O:array", &c, &initial))
|
||||||
|
|
|
@ -95,7 +95,7 @@ deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
dequeobject *deque;
|
dequeobject *deque;
|
||||||
block *b;
|
block *b;
|
||||||
|
|
||||||
if (!_PyArg_NoKeywords("deque()", kwds))
|
if (type == &deque_type && !_PyArg_NoKeywords("deque()", kwds))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* create dequeobject structure */
|
/* create dequeobject structure */
|
||||||
|
|
|
@ -681,7 +681,7 @@ cycle_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
PyObject *saved;
|
PyObject *saved;
|
||||||
cycleobject *lz;
|
cycleobject *lz;
|
||||||
|
|
||||||
if (!_PyArg_NoKeywords("cycle()", kwds))
|
if (type == &cycle_type && !_PyArg_NoKeywords("cycle()", kwds))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!PyArg_UnpackTuple(args, "cycle", 1, 1, &iterable))
|
if (!PyArg_UnpackTuple(args, "cycle", 1, 1, &iterable))
|
||||||
|
@ -831,7 +831,7 @@ dropwhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
PyObject *it;
|
PyObject *it;
|
||||||
dropwhileobject *lz;
|
dropwhileobject *lz;
|
||||||
|
|
||||||
if (!_PyArg_NoKeywords("dropwhile()", kwds))
|
if (type == &dropwhile_type && !_PyArg_NoKeywords("dropwhile()", kwds))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!PyArg_UnpackTuple(args, "dropwhile", 2, 2, &func, &seq))
|
if (!PyArg_UnpackTuple(args, "dropwhile", 2, 2, &func, &seq))
|
||||||
|
@ -975,7 +975,7 @@ takewhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
PyObject *it;
|
PyObject *it;
|
||||||
takewhileobject *lz;
|
takewhileobject *lz;
|
||||||
|
|
||||||
if (!_PyArg_NoKeywords("takewhile()", kwds))
|
if (type == &takewhile_type && !_PyArg_NoKeywords("takewhile()", kwds))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!PyArg_UnpackTuple(args, "takewhile", 2, 2, &func, &seq))
|
if (!PyArg_UnpackTuple(args, "takewhile", 2, 2, &func, &seq))
|
||||||
|
@ -1120,7 +1120,7 @@ islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
Py_ssize_t numargs;
|
Py_ssize_t numargs;
|
||||||
isliceobject *lz;
|
isliceobject *lz;
|
||||||
|
|
||||||
if (!_PyArg_NoKeywords("islice()", kwds))
|
if (type == &islice_type && !_PyArg_NoKeywords("islice()", kwds))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!PyArg_UnpackTuple(args, "islice", 2, 4, &seq, &a1, &a2, &a3))
|
if (!PyArg_UnpackTuple(args, "islice", 2, 4, &seq, &a1, &a2, &a3))
|
||||||
|
@ -1311,7 +1311,7 @@ starmap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
PyObject *it;
|
PyObject *it;
|
||||||
starmapobject *lz;
|
starmapobject *lz;
|
||||||
|
|
||||||
if (!_PyArg_NoKeywords("starmap()", kwds))
|
if (type == &starmap_type && !_PyArg_NoKeywords("starmap()", kwds))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!PyArg_UnpackTuple(args, "starmap", 2, 2, &func, &seq))
|
if (!PyArg_UnpackTuple(args, "starmap", 2, 2, &func, &seq))
|
||||||
|
@ -1443,7 +1443,7 @@ imap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
imapobject *lz;
|
imapobject *lz;
|
||||||
Py_ssize_t numargs, i;
|
Py_ssize_t numargs, i;
|
||||||
|
|
||||||
if (!_PyArg_NoKeywords("imap()", kwds))
|
if (type == &imap_type && !_PyArg_NoKeywords("imap()", kwds))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
numargs = PyTuple_Size(args);
|
numargs = PyTuple_Size(args);
|
||||||
|
@ -1625,7 +1625,7 @@ chain_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
PyObject *ittuple;
|
PyObject *ittuple;
|
||||||
|
|
||||||
if (!_PyArg_NoKeywords("chain()", kwds))
|
if (type == &chain_type && !_PyArg_NoKeywords("chain()", kwds))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* obtain iterators */
|
/* obtain iterators */
|
||||||
|
@ -1768,7 +1768,7 @@ ifilter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
PyObject *it;
|
PyObject *it;
|
||||||
ifilterobject *lz;
|
ifilterobject *lz;
|
||||||
|
|
||||||
if (!_PyArg_NoKeywords("ifilter()", kwds))
|
if (type == &ifilter_type && !_PyArg_NoKeywords("ifilter()", kwds))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!PyArg_UnpackTuple(args, "ifilter", 2, 2, &func, &seq))
|
if (!PyArg_UnpackTuple(args, "ifilter", 2, 2, &func, &seq))
|
||||||
|
@ -1912,7 +1912,8 @@ ifilterfalse_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
PyObject *it;
|
PyObject *it;
|
||||||
ifilterfalseobject *lz;
|
ifilterfalseobject *lz;
|
||||||
|
|
||||||
if (!_PyArg_NoKeywords("ifilterfalse()", kwds))
|
if (type == &ifilterfalse_type &&
|
||||||
|
!_PyArg_NoKeywords("ifilterfalse()", kwds))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!PyArg_UnpackTuple(args, "ifilterfalse", 2, 2, &func, &seq))
|
if (!PyArg_UnpackTuple(args, "ifilterfalse", 2, 2, &func, &seq))
|
||||||
|
@ -2054,7 +2055,7 @@ count_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
countobject *lz;
|
countobject *lz;
|
||||||
Py_ssize_t cnt = 0;
|
Py_ssize_t cnt = 0;
|
||||||
|
|
||||||
if (!_PyArg_NoKeywords("count()", kwds))
|
if (type == &count_type && !_PyArg_NoKeywords("count()", kwds))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "|n:count", &cnt))
|
if (!PyArg_ParseTuple(args, "|n:count", &cnt))
|
||||||
|
@ -2153,7 +2154,7 @@ izip_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
Py_ssize_t tuplesize = PySequence_Length(args);
|
Py_ssize_t tuplesize = PySequence_Length(args);
|
||||||
|
|
||||||
if (!_PyArg_NoKeywords("izip()", kwds))
|
if (type == &izip_type && !_PyArg_NoKeywords("izip()", kwds))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* args must be a tuple */
|
/* args must be a tuple */
|
||||||
|
@ -2336,7 +2337,7 @@ repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
PyObject *element;
|
PyObject *element;
|
||||||
Py_ssize_t cnt = -1;
|
Py_ssize_t cnt = -1;
|
||||||
|
|
||||||
if (!_PyArg_NoKeywords("repeat()", kwds))
|
if (type == &repeat_type && !_PyArg_NoKeywords("repeat()", kwds))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O|n:repeat", &element, &cnt))
|
if (!PyArg_ParseTuple(args, "O|n:repeat", &element, &cnt))
|
||||||
|
|
Loading…
Reference in New Issue