]> granicus.if.org Git - python/commitdiff
Bug #1486663: don't reject keyword arguments for subclasses of builtin
authorGeorg Brandl <georg@python.org>
Sun, 21 Jan 2007 10:28:56 +0000 (10:28 +0000)
committerGeorg Brandl <georg@python.org>
Sun, 21 Jan 2007 10:28:56 +0000 (10:28 +0000)
types.
 (backport from rev. 53509)

Lib/test/test_array.py
Lib/test/test_deque.py
Lib/test/test_itertools.py
Lib/test/test_random.py
Misc/NEWS
Modules/_randommodule.c
Modules/arraymodule.c
Modules/collectionsmodule.c
Modules/itertoolsmodule.c

index 06f13cd2b7f3648d8a2ea9388a35e273abb580ba..63e7f4ebb68fe38fe428e8f39d5c6eb22f742641 100755 (executable)
@@ -12,6 +12,10 @@ from cPickle import loads, dumps
 class ArraySubclass(array.array):
     pass
 
+class ArraySubclassWithKwargs(array.array):
+    def __init__(self, typecode, newarg=None):
+        array.array.__init__(typecode)
+
 tests = [] # list to accumulate all tests
 typecodes = "cubBhHiIlLfd"
 
@@ -683,6 +687,9 @@ class BaseTest(unittest.TestCase):
                 b = array.array('B', range(64))
             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):
index 35e153653299133e92a610515fafb1bc36a1f2f6..1d996eee9f9f9ec01a5d9abe7f1ce737ad308140 100644 (file)
@@ -486,6 +486,16 @@ class TestSubclass(unittest.TestCase):
         d1 == d2   # not clear if this is supposed to be True or False,
                    # 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 = """
@@ -599,6 +609,7 @@ def test_main(verbose=None):
         TestBasic,
         TestVariousIteratorArgs,
         TestSubclass,
+        TestSubclassWithKwargs,
     )
 
     test_support.run_unittest(*test_classes)
index 2baa50755403c96a39329e477dade7418cc3a658..5e375c9b526d1067a4ee1d5191f628b974194d6c 100644 (file)
@@ -740,6 +740,21 @@ class RegressionTests(unittest.TestCase):
         self.assertRaises(AssertionError, list, cycle(gen1()))
         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
 
 
@@ -934,7 +949,8 @@ __test__ = {'libreftest' : libreftest}
 
 def test_main(verbose=None):
     test_classes = (TestBasicOps, TestVariousIteratorArgs, TestGC,
-                    RegressionTests, LengthTransparency)
+                    RegressionTests, LengthTransparency,
+                    SubclassWithKwargsTest)
     test_support.run_unittest(*test_classes)
 
     # verify reference counting
index 6c326358290b74d462b868f395a1ed9487728ba0..6ddfb813e902981b2432b7caf653b7a75c3036de 100644 (file)
@@ -516,6 +516,14 @@ class TestModule(unittest.TestCase):
         # tests validity but not completeness of the __all__ list
         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):
     testclasses =    [WichmannHill_TestBasicOps,
                       MersenneTwister_TestBasicOps,
index e16ba883ef90a54c3a4a17854e226fc7938ca52d..787479890f8f6c6ad4839d3437fbebc9bf348383 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -91,6 +91,9 @@ Core and builtins
 Extension Modules
 -----------------
 
+- Bug #1486663: don't reject keyword arguments for subclasses of builtin
+  types.
+
 - The version number of the ctypes package was changed to "1.0.2".
 
 - Patch #1544279: Improve thread-safety of the socket module by moving
index bd1c9d39b1b7d26d5e93fd89586df7961b4ef788..591947e47e4d1f45758d4c1a2a6b4ecab0bf802d 100644 (file)
@@ -481,7 +481,7 @@ random_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
        RandomObject *self;
        PyObject *tmp;
 
-       if (!_PyArg_NoKeywords("Random()", kwds))
+       if (type == &Random_Type && !_PyArg_NoKeywords("Random()", kwds))
                return NULL;
 
        self = (RandomObject *)type->tp_alloc(type, 0);
index 9de14fd060d29a648efaa05ec3612983966cde99..210ada60f72483c23b33803500866cefdd57a8f3 100644 (file)
@@ -1797,7 +1797,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
        PyObject *initial = NULL, *it = NULL;
        struct arraydescr *descr;
        
-       if (!_PyArg_NoKeywords("array.array()", kwds))
+       if (type == &Arraytype && !_PyArg_NoKeywords("array.array()", kwds))
                return NULL;
 
        if (!PyArg_ParseTuple(args, "c|O:array", &c, &initial))
index a0570cde373c201ac929b86410a7e2b2efec1ca5..a4cdcfaf52dfb456ad6b4cfa2f174d8479e2965a 100644 (file)
@@ -95,7 +95,7 @@ deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
        dequeobject *deque;
        block *b;
 
-       if (!_PyArg_NoKeywords("deque()", kwds))
+       if (type == &deque_type && !_PyArg_NoKeywords("deque()", kwds))
                return NULL;
 
        /* create dequeobject structure */
index 7fcbb103667a81aa83c6b32771cf8c24719c0d20..7896143b084f3d081e0e43c371f8767b7c2dbad0 100644 (file)
@@ -681,7 +681,7 @@ cycle_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
        PyObject *saved;
        cycleobject *lz;
 
-       if (!_PyArg_NoKeywords("cycle()", kwds))
+       if (type == &cycle_type && !_PyArg_NoKeywords("cycle()", kwds))
                return NULL;
 
        if (!PyArg_UnpackTuple(args, "cycle", 1, 1, &iterable))
@@ -831,7 +831,7 @@ dropwhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
        PyObject *it;
        dropwhileobject *lz;
 
-       if (!_PyArg_NoKeywords("dropwhile()", kwds))
+       if (type == &dropwhile_type && !_PyArg_NoKeywords("dropwhile()", kwds))
                return NULL;
 
        if (!PyArg_UnpackTuple(args, "dropwhile", 2, 2, &func, &seq))
@@ -975,7 +975,7 @@ takewhile_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
        PyObject *it;
        takewhileobject *lz;
 
-       if (!_PyArg_NoKeywords("takewhile()", kwds))
+       if (type == &takewhile_type && !_PyArg_NoKeywords("takewhile()", kwds))
                return NULL;
 
        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;
        isliceobject *lz;
 
-       if (!_PyArg_NoKeywords("islice()", kwds))
+       if (type == &islice_type && !_PyArg_NoKeywords("islice()", kwds))
                return NULL;
 
        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;
        starmapobject *lz;
 
-       if (!_PyArg_NoKeywords("starmap()", kwds))
+       if (type == &starmap_type && !_PyArg_NoKeywords("starmap()", kwds))
                return NULL;
 
        if (!PyArg_UnpackTuple(args, "starmap", 2, 2, &func, &seq))
@@ -1443,7 +1443,7 @@ imap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
        imapobject *lz;
        Py_ssize_t numargs, i;
 
-       if (!_PyArg_NoKeywords("imap()", kwds))
+       if (type == &imap_type && !_PyArg_NoKeywords("imap()", kwds))
                return NULL;
 
        numargs = PyTuple_Size(args);
@@ -1625,7 +1625,7 @@ chain_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
        Py_ssize_t i;
        PyObject *ittuple;
 
-       if (!_PyArg_NoKeywords("chain()", kwds))
+       if (type == &chain_type && !_PyArg_NoKeywords("chain()", kwds))
                return NULL;
 
        /* obtain iterators */
@@ -1768,7 +1768,7 @@ ifilter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
        PyObject *it;
        ifilterobject *lz;
 
-       if (!_PyArg_NoKeywords("ifilter()", kwds))
+       if (type == &ifilter_type && !_PyArg_NoKeywords("ifilter()", kwds))
                return NULL;
 
        if (!PyArg_UnpackTuple(args, "ifilter", 2, 2, &func, &seq))
@@ -1912,7 +1912,8 @@ ifilterfalse_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
        PyObject *it;
        ifilterfalseobject *lz;
 
-       if (!_PyArg_NoKeywords("ifilterfalse()", kwds))
+       if (type == &ifilterfalse_type &&
+           !_PyArg_NoKeywords("ifilterfalse()", kwds))
                return NULL;
 
        if (!PyArg_UnpackTuple(args, "ifilterfalse", 2, 2, &func, &seq))
@@ -2054,7 +2055,7 @@ count_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
        countobject *lz;
        Py_ssize_t cnt = 0;
 
-       if (!_PyArg_NoKeywords("count()", kwds))
+       if (type == &count_type && !_PyArg_NoKeywords("count()", kwds))
                return NULL;
 
        if (!PyArg_ParseTuple(args, "|n:count", &cnt))
@@ -2153,7 +2154,7 @@ izip_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
        PyObject *result;
        Py_ssize_t tuplesize = PySequence_Length(args);
 
-       if (!_PyArg_NoKeywords("izip()", kwds))
+       if (type == &izip_type && !_PyArg_NoKeywords("izip()", kwds))
                return NULL;
 
        /* args must be a tuple */
@@ -2336,7 +2337,7 @@ repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
        PyObject *element;
        Py_ssize_t cnt = -1;
 
-       if (!_PyArg_NoKeywords("repeat()", kwds))
+       if (type == &repeat_type && !_PyArg_NoKeywords("repeat()", kwds))
                return NULL;
 
        if (!PyArg_ParseTuple(args, "O|n:repeat", &element, &cnt))