I want to use collections.abc.Sequence on top of some C++ data.
What is the best way to do this?
The only way I have found is to have a cdef class and a normal python class that inherits the cdef class and the mixin. This creates two classes.
The following is what I have tried and the results.
# cython: language_level=3, boundscheck=False, wraparound=False
# distutils: language = c++
from collections.abc import Sequence
from libcpp.vector cimport vector
from libc.stdint cimport int64_t
cdef class _MySequence:
cdef vector[int64_t] v
def __init__(self, *v: int):
self.v = v
def __getitem__(self, item):
return tuple(self.v)[item]
def __len__(self) -> int:
return self.v.size()
class MySequence1(_MySequence, Sequence[int]):
pass
# First base of 'MySequence2' is not an extension type
# cdef class MySequence2(Sequence[int]):
# cdef vector[int64_t] v
#
# def __init__(self, *v: int):
# self.v = v
#
# def __getitem__(self, item):
# return tuple(self.v)[item]
#
# def __len__(self) -> int:
# return self.v.size()
# Compiles fine but errors when importing
# TypeError: type() doesn't support MRO entry resolution; use types.new_class()
# cdef class MySequence3(object, Sequence[int]):
# cdef vector[int64_t] v
#
# def __init__(self, *v: int):
# self.v = v
#
# def __getitem__(self, item):
# return tuple(self.v)[item]
#
# def __len__(self) -> int:
# return self.v.size()
# cdef class BaseClass:
# pass
#
#
# # Same as 3
# # TypeError: type() doesn't support MRO entry resolution; use types.new_class()
# cdef class MySequence4(BaseClass, Sequence[int]):
# cdef vector[int64_t] v
#
# def __init__(self, *v: int):
# self.v = v
#
# def __getitem__(self, item):
# return tuple(self.v)[item]
#
# def __len__(self) -> int:
# return self.v.size()