mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	Bug #1486663: don't reject keyword arguments for subclasses of builtin
types.
This commit is contained in:
		
							parent
							
								
									aef4c6bc00
								
							
						
					
					
						commit
						b84c13792d
					
				
					 9 changed files with 62 additions and 16 deletions
				
			
		|  | @ -12,6 +12,10 @@ | |||
| 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 @@ def test_bug_782369(self): | |||
|                 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): | ||||
|  |  | |||
|  | @ -486,6 +486,16 @@ def __iter__(self): | |||
|         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) | ||||
|  |  | |||
|  | @ -740,6 +740,21 @@ def gen2(x): | |||
|         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 @@ def gen2(x): | |||
| 
 | ||||
| def test_main(verbose=None): | ||||
|     test_classes = (TestBasicOps, TestVariousIteratorArgs, TestGC, | ||||
|                     RegressionTests, LengthTransparency) | ||||
|                     RegressionTests, LengthTransparency, | ||||
|                     SubclassWithKwargsTest) | ||||
|     test_support.run_unittest(*test_classes) | ||||
| 
 | ||||
|     # verify reference counting | ||||
|  |  | |||
|  | @ -515,6 +515,14 @@ def test__all__(self): | |||
|         # 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, | ||||
|  |  | |||
|  | @ -313,6 +313,9 @@ Library | |||
| 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 | ||||
|   C99 _Bool. | ||||
| 
 | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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)) | ||||
|  |  | |||
|  | @ -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 */ | ||||
|  |  | |||
|  | @ -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)) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Georg Brandl
						Georg Brandl