range(Instance) vs. foo[Instance] 
Author Message
 range(Instance) vs. foo[Instance]

: 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;
        }



Tue, 25 Dec 2001 03:00:00 GMT  
 range(Instance) vs. foo[Instance]
: 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;
        }



Tue, 25 Dec 2001 03:00:00 GMT  
 
 [ 2 post ] 

 Relevant Pages 

1. instances of classes and instances of instances

2. Can event from instance propagate to other instances?

3. Instances incorrectly sharing instance variables?

4. Convert single instance tcl program to multiple instances...

5. foo.py vs. foo.pyc

6. Class vs Instance methods

7. Class vs Instance methods

8. Class side vs Instance Side??

9. Class methods vs Instance methods

10. Class method vs instance method???

11. Class method vs instance method???

12. Types (was: Attribute vs Instance Variable)

 

 
Powered by phpBB® Forum Software