Передача аргументов в tp_new и tp_init из подтипов в Python C API

Первоначально я задал этот вопрос в списке capi-sig Python:Как передать аргументы в tp_new и tp_init из подтипов?

Я читаю PythonPEP-253 на подтип и есть много хороших рекомендаций о том, как структурировать типы, звонитеtp_new а такжеtp_init слоты и т. д.

Но в нем отсутствует важное примечание о передаче аргументов из sub в супертип. КажетсяPEP-253 незакончен согласно примечанию:

(XXX There should be a paragraph or two about argument passing here.)

Итак, я пытаюсь экстраполировать некоторые стратегиихорошо известно из подтипов классов Pythonособенности техник, которые на каждом уровне снимают аргументы и т. д.

Я ищу методы для достижения подобного эффекта, но использую простойPython C API (3.x):

class Shape:
    def __init__(self, shapename, **kwds):
        self.shapename = shapename
        super().__init__(**kwds)

class ColoredShape(Shape):
    def __init__(self, color, **kwds):
        self.color = color
        super().__init__(**kwds)

Что будет эквивалентно в Python C API?

Как бороться с подобной ситуацией, но с аргументами, специфичными для производного класса, ожидаемого в другом порядке? Это аргументы, данные в конце кортежа args (илиkwds dict, я полагаю, принцип будет таким же).

Вот некоторый (псевдо) код, который иллюстрирует ситуацию:

class Base:
   def __init__(self, x, y, z):
      self.x = x
      self.y = y
      self.z = z

class Derived(Base):
   def __init__(self, x, y, a):
      self.a = a
      super().__init__(x, y, None):

Обратите внимание, еслиa ожидалось сначала:

Derived.__init__(self, a, x, y)

это было бы похоже на ситуациюShape а такжеColoredShape выше. Я думаю, было бы легче иметь дело с этим.

Может ли кто-нибудь помочь разобраться с пропавшим без вести?XXX комментарий, упомянутый выше, и правильная техника для передачи аргументов от подтипа до супертипа (ов) в конструкции?

ОБНОВЛЕНИЕ 2012-07-17:

Вдохновленныйответ Ecatmur ниже я просмотрел источники Python 3 и нашелdefdict_init конструкторcollections.defaultdict Тип объекта интересный. Тип является производным отPyDictObject и его конструктор принимает дополнительный аргументdefault_factory, Подпись конструктора в классе Python такова:

class collections.defaultdict([default_factory[, ...]])

Теперь вот какdefault_factory снято с оригиналаargs кортеж, поэтому остальные аргументы направляютсяtp_init базового типа, этоPyDictObject:

int result;
PyObject *newargs;
Py_ssize_t n = PyTuple_GET_SIZE(args);
...
newargs = PySequence_GetSlice(args, 1, n);
...
result = PyDict_Type.tp_init(self, newargs, kwds);

Обратите внимание, это урезанное присутствие только соответствующей частиdefdict_init функция.

Ответы на вопрос(3)

Ваш ответ на вопрос