d = {}; d[0:1] = 1; d[0:1] = 2; print d[0:1]

Robin Thomas robin.thomas at starmedia.net
Thu Mar 1 01:58:49 EST 2001


At 06:06 AM 3/1/01 +0000, Donn Cave wrote:

>If it helps, you ruined my day.

Now I'm not alone!


>I think we might be able to do better.  I hacked in a quick fix
>in ceval.c that looks to me like it has the desired effect without
>closing the door to intentional slice keys (however unlikely.)

Cool. I think that the abstract object layer saves us, though:

- slice assignment is handled by PySequence_SetSlice
- *intentional* assignment of slice object is handled by PyObject_SetItem

PySequence_SetSlice, strangely, has a big chunk of code expressly written 
to support slice assignment to mapping objects. From Objects/abstract.c 
below. If we remove that code, we get the same effect.

int
PySequence_SetSlice(PyObject *s, int i1, int i2, PyObject *o)
{
         PySequenceMethods *m;
         PyMappingMethods *mp;

         if (s == NULL) {
                 null_error();
                 return -1;
         }

         m = s->ob_type->tp_as_sequence;
         if (m && m->sq_ass_slice) {
                 if (i1 < 0 || i2 < 0) {
                         if (m->sq_length) {
                                 int l = (*m->sq_length)(s);
                                 if (l < 0)
                                         return -1;
                                 if (i1 < 0)
                                         i1 += l;
                                 if (i2 < 0)
                                         i2 += l;
                         }
                 }
                 return m->sq_ass_slice(s, i1, i2, o);
         /* the evil begins */
         } else if ((mp = s->ob_type->tp_as_mapping) && mp->mp_ass_subscript) {
                 int res;
                 PyObject *slice = sliceobj_from_intint(i1, i2);
                 if (!slice)
                         return -1;
                 res = mp->mp_ass_subscript(s, slice, o);
                 Py_DECREF(slice);
                 return res;
         }

         type_error("object doesn't support slice assignment");
         return -1;
}

Anybody have an explanation why this behavior was desired?

>I don't know if this is the answer, but it at least demonstrates
>that [:] and slice() can be separate issues at some level.

They're separate issues even for lists:

 >>> l = []
 >>> l[0:1] = [1]
 >>> f = slice(0,1)
 >>> l[f] = [1]
Traceback (innermost last):
   File "<pyshell#21>", line 1, in ?
     l[f]= [1]
TypeError: sequence index must be integer

The question remains: should slice objects be hashable/comparable so that

 >>> slice(0,1) == slice(0,1)
1

I say YES YES YES. What do you say?


--
Robin Thomas
Engineering
StarMedia Network, Inc.
robin.thomas at starmedia.net





More information about the Python-list mailing list