homepage

This issue tracker has been migrated to GitHub , and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: xrange() builtin accepts keyword arg silently
Type: Stage:
Components: Library (Lib) Versions:
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: georg.brandl Nosy List: blais, georg.brandl, georg.brandl, rhettinger, terry.reedy
Priority: high Keywords:

Created on 2005年02月09日 16:57 by blais, last changed 2022年04月11日 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
PyArg_NoKeywords.patch georg.brandl, 2005年08月25日 20:21
Messages (7)
msg24217 - (view) Author: Martin Blais (blais) * (Python committer) Date: 2005年02月09日 16:57
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$ 
msg24218 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2005年02月16日 22:21
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.
msg24219 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2005年06月09日 21:04
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.
msg24220 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2005年08月25日 13:20
Logged In: YES 
user_id=1188172
Please review. Should I work on a patch to buffer, set and
slice, too?
msg24221 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2005年08月25日 14:35
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.
msg24222 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2005年08月25日 20:21
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)
msg24223 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2005年08月26日 06:45
Logged In: YES 
user_id=1188172
Committed. Must the new API function be somehow documented?
Commit report follows:
Checking in Python/getargs.c;
new revision: 2.106; previous revision: 2.105
Checking in Include/modsupport.h;
new revision: 2.42; previous revision: 2.41
Checking in Objects/rangeobject.c;
new revision: 2.55; previous revision: 2.54
Checking in Objects/setobject.c;
new revision: 1.56; previous revision: 1.55
Checking in Objects/bufferobject.c;
new revision: 2.27; previous revision: 2.26
Checking in Objects/sliceobject.c;
new revision: 2.23; previous revision: 2.22
Checking in Modules/arraymodule.c;
new revision: 2.99; previous revision: 2.98
Checking in Modules/itertoolsmodule.c;
new revision: 1.41; previous revision: 1.40
Checking in Modules/operator.c;
new revision: 2.31; previous revision: 2.30
Checking in Modules/_randommodule.c;
new revision: 1.8; previous revision: 1.7
Checking in Modules/zipimport.c;
new revision: 1.19; previous revision: 1.18
Checking in Modules/collectionsmodule.c;
new revision: 1.39; previous revision: 1.38
Checking in Python/getargs.c;
new revision: 2.102.2.3; previous revision: 2.102.2.2
Checking in Include/modsupport.h;
new revision: 2.41.4.1; previous revision: 2.41
Checking in Objects/rangeobject.c;
new revision: 2.53.2.1; previous revision: 2.53
Checking in Objects/setobject.c;
new revision: 1.31.2.4; previous revision: 1.31.2.3
Checking in Objects/bufferobject.c;
new revision: 2.26.2.1; previous revision: 2.26
Checking in Objects/sliceobject.c;
new revision: 2.22.4.1; previous revision: 2.22
Checking in Modules/arraymodule.c;
new revision: 2.97.2.1; previous revision: 2.97
Checking in Modules/itertoolsmodule.c;
new revision: 1.39.2.1; previous revision: 1.39
Checking in Modules/operator.c;
new revision: 2.29.4.1; previous revision: 2.29
Checking in Modules/_randommodule.c;
new revision: 1.7.4.1; previous revision: 1.7
Checking in Modules/zipimport.c;
new revision: 1.18.2.1; previous revision: 1.18
Checking in Modules/collectionsmodule.c;
new revision: 1.36.2.1; previous revision: 1.36
History
Date User Action Args
2022年04月11日 14:56:09adminsetgithub: 41553
2005年02月09日 16:57:05blaiscreate

AltStyle によって変換されたページ (->オリジナル) /