[Python-Dev] slice subscripts for sequences and mappings

Eli Bendersky eliben at gmail.com
Sun Mar 4 04:37:37 CET 2012


>> Thomas Wouters, 03.03.2012 21:59:
>> > Why even have separate tp_as_sequence and tp_as_mapping anymore? That
>> > particular distinction never existed for Python types, so why should it
>> > exist for C types at all? I forget if there was ever a real point to it,
>> > but all it seems to do now is create confusion, what with many sequence
>> > types implementing both, and PyMapping_Check() and PySequence_Check()
>> > doing
>> > seemingly random things to come up with somewhat sensible answers. Do
>> > note
>> > that the dict type actually implements tp_as_sequence (in order to
>> > support
>> > containtment tests) and that PySequence_Check() has to explicitly return
>> > 0
>> > for dicts -- which means that it will give the "wrong" answer for
>> > another
>> > type that behaves exactly like dicts.
>> >
>> > Getting rid of the misleading distinction seems like a much better idea
>> > than trying to re-conflate some of the issues.
>>
>> We're too far away from the release of Python 4 to change something with
>> that kind of impact, though.
>
>
> It's not hard to do this in a backward-compatible way. Either grow one of
> the tp_as_* to include everything a 'unified' tp_as_everything struct would
> need, or add a new tp_as_everything slot in the type struct. Then add a
> tp_flag to indicate that the type has this new layout/slot and guard all
> uses of the new slots with a check for that flag. If the type doesn't have
> the new layout or doesn't have it or the slots in it set, the code can fall
> back to the old try-one-and-then-the-other behaviour of dealing with
> tp_as_sequence and tp_as_mapping.
>
> (Let's not forget about tp_as_sequence.sq_concat, tp_as_number.nb_add,
> tp_as_sequence.sq_repeat and tp_as_number.nb_mul either.)
>

There's nothing to unify, really, since PyMappingMethods is just a
subset of PySequenceMethods:

typedef struct {
    lenfunc mp_length;
    binaryfunc mp_subscript;
    objobjargproc mp_ass_subscript;
} PyMappingMethods;

with the small difference that in PySequenceMethods sq_item and
sq_ass_item just accept numeric indices. However, if PySequenceMethods
has the was_sq_sclies and was_sq_ass_slice fields are reinstated to
accept a generic PyObject, PyMappingMethods will be a true subset.

If we look at the code, this becomes even clearer: in a full grep on
the Python 3.3 source, there is no object that defines tp_as_mapping
but does not also define tp_as_sequence, except Modules/_sqlite/row.c
[I'm not familiar enough with the _sqlite module, but there's a chance
it would make sense for the Row to be a sequence too].

Eli


More information about the Python-Dev mailing list