Bugs item #1119418, was opened at 2005-02-09 17:57 Message generated for change (Comment added) made by birkenfeld You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1119418&group_id=5470
Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: Python Library Group: None Status: Open Resolution: None Priority: 6 Submitted By: Martin Blais (blais) >Assigned to: Raymond Hettinger (rhettinger) Summary: xrange() builtin accepts keyword arg silently Initial Comment: Calling ``xrange(10, 100, step=10)`` results in a xrange(10, 100) iterator silently. In contrast, ``range(10, 100, step=10)`` raises an exception. See test program below. Two possible fixes: 1. fix xrange() so that it returns a xrange(10, 100, 10) iterator 2. make sure that xrange() raises an exception too. #!/usr/bin/env python def foo( min_, max_, step=1 ): print min_, max_, step print '====================' foo(10, 100, 10) foo(10, 100, step=10) print '====================' print xrange(10, 100, 10) print xrange(10, 100, step=10) print '====================' print range(10, 100, 10) print range(10, 100, step=10) elbow:/usr/.../lib/python2.4$ /tmp/a.py ==================== 10 100 10 10 100 10 ==================== xrange(10, 100, 10) xrange(10, 100) ==================== [10, 20, 30, 40, 50, 60, 70, 80, 90] Traceback (most recent call last): File "/tmp/a.py", line 16, in ? print range(10, 100, step=10) TypeError: range() takes no keyword arguments > /tmp/a.py(16)?() -> print range(10, 100, step=10) (Pdb) elbow:/usr/.../lib/python2.4$ ---------------------------------------------------------------------- >Comment By: Reinhold Birkenfeld (birkenfeld) Date: 2005-08-25 22:21 Message: Logged In: YES user_id=1188172 Attaching a huge patch. It introduces the function you described, and calls it in the constructors of xrange, set, frozenset, buffer and slice. Moreover, I found it to be necessary in objects in the following modules: - array (array) - itertools (cycle, dropwhile, takewhile, islice, imap, chain, ifilter, count, izip, repeat) - operator (attrgetter, itemgetter) - _random (Random) - zipimport (zipimporter) - collections (deque) ---------------------------------------------------------------------- Comment By: Raymond Hettinger (rhettinger) Date: 2005-08-25 16:35 Message: Logged In: YES user_id=80475 xrange() needs to be kept closely parallel with range() . Accordingly, it should not sprout keyword arguments. For all of these, I think the solution is to raise a TypeError when keyword arguments are supplied to functions/types that don't handle them. Encapsulate the logic in a new internal API function: int _PyArg_NoKeywords(char *funcname, PyObject *kwds) { if (kwds == NULL) return 1; if (!PyDict_CheckExact(kwds)){ bad internal call return 0; } if (PyDict_Size(kwds) == 0) return 1; set_exc_typeerror(funcname does not take kw args) return 0; } Then go through the code finding all the type constructors (grep for PyTypeObject) and add the error check if the kwds arg is being ignored). For example: range_new(PyTypeObject *type, PyObject *args, PyObject *kw) { if (!_PyArg_NoKeywords("xrange", kw)) return NULL; . . . Be sure to add test cases for every constructor that gets changed. Also, go ahead an backport to Py2.4.2. ---------------------------------------------------------------------- Comment By: Reinhold Birkenfeld (birkenfeld) Date: 2005-08-25 15:20 Message: Logged In: YES user_id=1188172 Please review. Should I work on a patch to buffer, set and slice, too? ---------------------------------------------------------------------- Comment By: Reinhold Birkenfeld (birkenfeld) Date: 2005-06-09 23:04 Message: Logged In: YES user_id=1188172 I delved deeper into this, and it seems that the difference is caused by range being a method (of bltinmodule, defined as METH_VARARGS), while xrange is a constructor for a rangeobject. Such constructor functions get three arguments (the type object, the args and the kw args), and when the kw args are not checked like in str(), they can pass freely and are ignored. I have attached a patch which changes the range object constructor (xrange) to accept keyword arguments. Other builtin types that need such a correction include buffer, set, slice. ---------------------------------------------------------------------- Comment By: Terry J. Reedy (tjreedy) Date: 2005-02-16 23:21 Message: Logged In: YES user_id=593130 Functions coded in C generally do not take keyword arguments. (Special coding is required to achieve otherwise.) In 2.2, range and xrange both followed this rule: >>> xrange(1,20,step=2) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: xrange() takes no keyword arguments >>> range(1,20,step=2) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: range() takes no keyword arguments So, removal of the error message by 2.4 seem to be a bug. Surprise: >>> str(object=1) '1' >>> str(i=2) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: 'i' is an invalid keyword argument for this function There is nothing in the doc(Lib Ref) or doc string of str vs. range and xrange that would lead me to expect this. I looked around CVS a bit to see if the past or possible future change was something simple, but I could not find source of error message in bltinmodule.c, ceval.c, getargs.c, rangeobject.c, or typeobject.c, so I will leave this to someone else. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1119418&group_id=5470 _______________________________________________ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com