I'd like to allow my extension objects to be passed into Python's len()
function, and I understand the way to do this is to implement the sq_length
member of PySequenceMethods
, but right now I don't have time to implement all the methods of the sequence protocol, and I can't figure out which of the methods are optional and which (if any) are required.
The documentation for tp_as_sequence
does not mention anything about optional members.
The documentation for PySequenceMethods
explicitly states that sq_item
, sq_ass_item
, sq_contains
, sq_inplace_concat
, and sq_inplace_repeat
can be left to NULL
.
Further, the documentation for sq_item
implies that sq_length
can also be left to NULL
:
If
sq_length
is NULL, the index is passed as is [...]
Which leaves sq_concat
and sq_repeat
. I'd be surprised if it weren't safe to also set these to NULL
, given that you can do so for all the other members (including sq_item
, and sq_length
, both of which seem more fundamental to the concept of a sequence than the others), but is this assumption actually correct?
If it's not safe to leave them NULL
, is it safe to implement them simply to set an error stating that these two functions are not supported and return NULL
?
All of them are optional.
Setting sq_item
to NULL
means that PySequence_Check()
fails, and so it isn't really a sequence - I don't know how "optional" you want to consider that.
All of the PySequence_*
methods check for NULL
pointers and will just set a Python TypeError
rather than crashing, so it's safe to set these members to NULL
. Just to show the two you were unsure about:
PySequence_Concat
and PySequence_Repeat
both have code of the form:
if (m && m->sq_repeat)
return m->sq_repeat(o, count);
It's pretty straightforward to go through the rest of the functions and see that they use the same pattern.