range(Instance) vs. foo[Instance]
Michael P. Reilly
arcege at shore.net
Fri Jul 9 09:08:02 EDT 1999
Jeff Epler <jepler at inetnebr.com> wrote:
: Suppose I have a class with __int__ defined:
: class c:
: def __init__(self, val):
: self.val = int(val)
: def __int__(self): return self.val
:>>> x=c(1)
:>>> range(x)
: [0]
:>>> (0,1,2)[x]
: Traceback (innermost last):
: File "<stdin>", line 1, in ?
: TypeError: sequence index must be integer
: It seems desirable that the subscript operator call x.__int__ just like
: range() must effectively do. Is there some reason why not?
: (Not the subscript operator in general, but the subscript operator for
: the builtin types of lists and tuples)
: I ask because I recently wrote a 5-minute hack on top of bytecodehacks that
: makes "integers" function as rational numbers in the interactive Python
: console---functions like "range" work, but subscripting of tuples and lists
: is broken.
: Jeff
Yup, this sounds like a bug, since [].insert( c(0), "spam") would work
as you expect. Some reasons to not have this would be:
* How do you handle complex numbers as subscripts,
* Strings containing numbers as subscripts.
But this looks like a holdover from older code. Myself, I'm not sure
if strings (containing a number) should be accepted.
I've submitted a patch to Guido and am including it here. This will
make all built-in sequences (strings, tuples and lists) perform an
implicit seq[int(subscr)] if subscr is not an int. The subscripting
will still fail if int() fails.
-Arcege
Index: Objects/abstract.c
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Objects/abstract.c,v
retrieving revision 2.27
diff -c -r2.27 abstract.c
*** abstract.c 1999/01/10 16:56:58 2.27
--- abstract.c 1999/07/09 12:30:03
***************
*** 228,233 ****
--- 228,234 ----
PyObject *key;
{
PyMappingMethods *m;
+ PyObject *tmp, *v;
if (o == NULL || key == NULL)
return null_error();
***************
*** 239,244 ****
--- 240,250 ----
if (o->ob_type->tp_as_sequence) {
if (PyInt_Check(key))
return PySequence_GetItem(o, PyInt_AsLong(key));
+ else if ((tmp = PyNumber_Int(key)) != NULL) {
+ v = PySequence_GetItem(o, PyInt_AsLong(tmp));
+ Py_DECREF(tmp);
+ return v;
+ }
return type_error("sequence index must be integer");
}
***************
*** 252,257 ****
--- 258,265 ----
PyObject *value;
{
PyMappingMethods *m;
+ PyObject *tmp;
+ int v;
if (o == NULL || key == NULL || value == NULL) {
null_error();
***************
*** 264,269 ****
--- 272,282 ----
if (o->ob_type->tp_as_sequence) {
if (PyInt_Check(key))
return PySequence_SetItem(o, PyInt_AsLong(key), value);
+ else if ((tmp = PyNumber_Int(key)) != NULL) {
+ v = PySequence_SetItem(o, PyInt_AsLong(tmp), value);
+ Py_DECREF(tmp);
+ return v;
+ }
type_error("sequence index must be integer");
return -1;
}
***************
*** 278,283 ****
--- 291,298 ----
PyObject *key;
{
PyMappingMethods *m;
+ PyObject *tmp;
+ int v;
if (o == NULL || key == NULL) {
null_error();
***************
*** 290,295 ****
--- 305,315 ----
if (o->ob_type->tp_as_sequence) {
if (PyInt_Check(key))
return PySequence_DelItem(o, PyInt_AsLong(key));
+ else if ((tmp = PyNumber_Int(key)) != NULL) {
+ v = PySequence_DelItem(o, PyInt_AsLong(tmp));
+ Py_DECREF(tmp);
+ return v;
+ }
type_error("sequence index must be integer");
return -1;
}
More information about the Python-list
mailing list