Справочник

Материал из pyhrol.ru
Перейти к: навигация, поиск
Другие языки:English 99% • ‎русский 100%


Содержание

Макросы

Питонизации

Питонизирующая функция/метод должна содержать макросы питонизации. Порядок следования макросов в функции/методе должен совпадать с порядком их следования в таблице:

Имя Аргументы Описание Обязательный Количество
PYHROL_PARSE_TUPLE_{M},

M ∈ [0, PYHROL_MAX_INPUT_ARGS];

const char *description, Tuples, {in} Пытается "разложить" Python-аргумент PyObject * по M переменным {in} в соответсвтвии с их типами, а также формирует форматную строку и справку. Аргумент description — описание кортежа, допускает значение NULL - [0, ∞)
PYHROL_AFTER_PARSE_TUPLE Tuples _args Управляет состоянием своего аргумента _args + 1
PYHROL_BUILD_VALUE_{N},

N ∈ [0, PYHROL_MAX_OUTPUT_ARGS];

const char *description, Tuples, {out} "Складывает" значения N переменных {out} в соответствии с их типами в возвращаемое значение PyObject *, а также формирует форматную строку и справку. Аргумент description — описание кортежа, допускает значение NULL - [0, ∞)
PYHROL_AFTER_BUILD_VALUE Tuples _args Управляет состоянием своего аргумента _args + 1
PYHROL_AFTER_EXECUTE_DEFAULT Tuples _args Завершает выполнение функции/метода. Возращаемым значением становятся переменные в первом из макросов PYHROL_BUILD_VALUE_{N} либо None, если таковых нет. Не совместим с PYHROL_AFTER_EXECUTE + 1
PYHROL_AFTER_EXECUTE Tuples, const uint8_t build_variant Завершает выполнение функции/метода. Возращаемым значением становятся переменные в макросе PYHROL_BUILD_VALUE_{N} с индексом build_variant. Нумерация с 0. Если build_variant выходит за пределы диапазона [0, N), вызывается исключение UseException. Макрос не совместим с PYHROL_AFTER_EXECUTE_DEFAULT, см примеры 0070, 0455

Макросы объявлены в заголовках pyhrol_macro.h, pyhrol_fmt_in_macro.h и pyhrol_fmt_out_macro.h. За исключением PYHROL_AFTER_EXECUTE используются в каждом примере

Регистрации

Нижеследующие макросы служат для упрощения записи шаблонных аргументов при регистрации функций/методов. За исключением PYHROL_REGISTER_GETSETER самостоятельно преобразуют имя функции/метода в C-строку, т. е. требуют на один аргумент меньше:

Имя Описание
PYHROL_REGISTER_FUNCTION см пример 0020 и ниже
PYHROL_REGISTER_FUNCTION_WITH_KEYWORDS см примеры 0050, 0120, 0840
PYHROL_REGISTER_FUNCTION_NO_ARGS см примеры 0010, 0030; функия не может содержать макросы PYHROL_PARSE_TUPLE_*, иначе ошибка AttributeError при попытке исполнения или зондировании, см пример 0920
PYHROL_REGISTER_METHOD
PYHROL_REGISTER_METHOD_WITH_KEYWORDS
PYHROL_REGISTER_METHOD_NO_ARGS
PYHROL_REGISTER_GETSETER см пример 0455
PYHROL_REGISTER_GETTER
PYHROL_REGISTER_SETTER

Макросы регистрации применимы далеко не во всех синтаксических конструкциях, а потому бесперспективны. Для регистрации статических методов макросы отсутствуют

Типы

Согласно руководству, тип переменной, преобразуемой в или из PyObject определяется форматной строкой, а обязанность следить за соответствием этой строки количеству и типам реальных переменных возлагается на программиста. Pyhrol же использует информацию о реальном типе переменной и на ее основе автоматически генерирует форматную строку. За небольшим исключением (1, 2) в полном соответствии с руководством. Исчерпывающий список всех поддерживаемых типов данных в нижеследующих таблицах:

Числовые

C-переменные нижеперечисленных типов включаются в макросы PYHROL_PARSE_TUPLE_{M} или PYHROL_BUILD_VALUE_{N} и на этапе исполнения автоматически включаются в форматную строку со спецификатором из колонки формат(in/out):

Формат C-тип typedef-ы Размер Примечание
in out i386 amd64 i386 amd64
Целые
b signed char int8_t 1
B,b B unsigned char uint8_t
h short[[ signed] int] int16_t 2
H short unsigned[ int] uint16_t
i [signed ]int int32_t,

ssize_t

int32_t 4 Следуя за форматом s, z, u, es, et, t или w становится частью формата s#, z#, u#, es#, et#, t# или w# соответственно
I unsigned int uint32_t,

size_t

uint32_t
l long[[ signed] int] time_t int64_t,

ssize_t, time_t

4 8
k unsigned long[ int] uint64_t,

size_t

L [signed ]long long[ int] int64_t 8
K unsigned long long[ int] uint64_t
n long[[ signed] int] Py_ssize_t 4 8 Форматная строка n не поддерживается но тип Py_ssize_t является синонимом l
Дробные
f float 4
d double 8

Остальные

C/C++-переменные нижеперечисленных типов включаются в макросы PYHROL_PARSE_TUPLE_{M} или PYHROL_BUILD_VALUE_{N}, иногда парами и тройками, и на этапе исполнения автоматически включаются в форматную строку со спецификатором из колонки формат(in/out):

Формат Python-тип C-тип Примечание
in out in out
Строковые
c string char Тип str длиной 1 байт
s string

unicode

const char *
s# const char *, int см пример 0110
s* Py_buffer *
z string

unicode None

const char * Включается опцией optNoneEnabled
z# const char *, int
z* Py_buffer *
u unicode Py_UNICODE * const Py_UNICODE *
u# Py_UNICODE *, int const Py_UNICODE *, int
es string

unicode or character buffer compatible object

const char, char *
et Включается опцией optNotRecode
es# const char, char *, int
et# Включается опцией optNotRecode
t# read-only

character buffer

Не поддерживаются
w read-write

character buffer

w#
w* read-write

byte-oriented buffer

S string PyStringObject *
S object const PyObject *
U unicode PyUnicodeObject *
Прочие
D complex Py_complex const Py_complex
O object PyObject * const PyObject * Включается опцией optIncrementReferenceCount
N см пример 0560
O! PyTypeObject,

PyObject *

PyTypeObject без PyObject не используется, см примеры 0090, 0550, а также argObject
O& TupleIn::in_conv_t,

const TupleIn::anything *

По отдельности не используются, см пример 0100
O& TupleOut::out_conv_t,

const TupleOut::anything *

() tuple Включается опцией optTuple, см пример 0455
[] list Включается опцией optList
{} dictionary Включается опцией optDictionary

Типы полей

Типы шаблонных аргументов метода TypeWrapper::m_add_member. Несоответствие типа ни одному из перечисленных — ошибка компиляции.

C-тип Python-тип Флаг Описание
Модфицируемый Константный
bool const bool bool T_BOOL
int8_t const int8_t int T_BYTE
int16_t const int16_t T_SHORT
int32_t const int32_t T_INT
long int const long int T_LONG
uint8_t const uint8_t long T_UBYTE
uint16_t const uint16_t T_USHORT
uint32_t const uint32_t T_UINT
unsigned long int const unsigned long int T_ULONG
long long int const long long int T_LONGLONG
unsigned long long int const unsigned long long int T_ULONGLONG
float const float float T_FLOAT
double const double T_DOUBLE
char const char str T_CHAR
char *, const char * T_STRING Только чтение по определению
char[] T_STRING_INPLACE Только чтение по определению. Используется флаг T_STRING. Массивы фиксированной длины, размер массива является частью шаблонного типа
T_OBJECT Не поддерживается в пользу T_OBJECT_EX
PyObject * const PyObject * T_OBJECT_EX
T_PYSSIZET Не поддерживается, является синонимом T_LONG

см пример 0440

Переменные CMake

Имя Описание
PYHROL_SAFE_MODE Отключает на этапе компиляции следующую фукциональность библиотеки Pyhrol:

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

Attention.png Модуль, вызывающий ошибки при инициализации и/или зондировании в нормальном режиме, при включении PYHROL_SAFE_MODE может вести себя непредсказуемо
PYHROL_MAX_INPUT_ARGS Количество макросов PYHROL_PARSE_TUPLE_{M}. По умолчанию 16
PYHROL_MAX_OUTPUT_ARGS Количество макросов PYHROL_BUILD_VALUE_{N}. По умолчанию 8

Переменные окружения

Следующие переменные окружения влияют на инициализацию модулей, написанных с использованием библиотеки Pyhrol:

Имя Описание
__PY_SHOW_CALLS Показать загруженные метаданные: функции, методы, конструкторы с именами, адресами и индексами. Условные обозначения:
  • f — функция, см пример 0010
  • m — метод, см пример 0420
  • < — метод для чтения атрибута, см примеры 0450, 0455
  • > — метод для записи атрибута, см примеры 0450, 0455
  • + — конструктор, см пример 0410
  • # — метод интерфейса Number Protocol
  • $ — метод интерфейса Sequence Protocol
  • = — метод интерфейса Mapping Protocol
  • * — прочие методы

Индекс состоит из офсета типа (для методов) и офсета метода/функции. В список включены только питонизированные объекты c характерной сигнатурой, поэтому там не будет методов итератора, деструкторов и т. д.

__PY_HACK_SIGNATURES Включить зондирование
PYHROL_TRACE Управление трассировкой, поведение идентично Container.set_trace_options
PYHROL_TUPLE_HEADER_FORMAT Управление форматом справки, поведение идентично Container.set_help_format
PYHROL_TUPLE_BODY_FORMAT
PYHROL_ERROR_HEADER_FORMAT
PYHROL_ERROR_BODY_FORMAT

Базовые классы

Все возможности C++-класса публикуются в Python-е посредством объекта PyTypeObject. Задача питонизации состоит только в правильном заполнении полей этого объекта. PyTypeObject "живет" внутри TypeBase и "знает" о питонизируемом классе только то, что его тип — T, весит он sizeof(T) байт и что для манипуляций над ним нужно дергать функции по указателю (если последний не NULL).

TypeBase обеспечивает минимальную функциональность питонизируемого типа T. Как правило T наследует от одного из потомков TypeBase в зависимости от специфики самого T:

Потомок Описание Примеры
TypeWrapper В отличие от TypePointer создает и удаляет экземпляры класса T. Не совместим с TypePointer, допускает непосредственную питонизацию полей Предназначен для питонизации динамических методов класса T 0420, 0450
TypePointer В отличие от TypeWrapper создает и удаляет указатели на экземпляры класса T. Не совместим с TypeWrapper, не поддерживает непосредственную питонизацию полей 0460
TypeSmart Помимо типа T, использует шаблон E, конвертируемый в T статическим конвертером E* (*C)(T *), так же являющимся шаблоном. Наследует от TypeWrapper, но в отличие от него питонизирует методы класса E. Применим для классов оберток. Например для типа weak_ptr<MyClass>:
  • T = weak_ptr<MyClass>
  • E = MyClass
  • E* (*C)(T *):
MyClass *from_weak(std::tr1::weak_ptr<MyClass> *ptr)
{
return ptr->lock().get();
}

Наследник может использовать как методы с типом T так и методы с типом E напрямую, в последнем случае TypeSmart вызывает конвертер E* (*C)(T *). На практике оказывается проще унаследовать от TypeWrapper и в каждом из методов вызывать конвертер самостоятельно

0480
TypeSpecial Питонизирует статические методы и методы класса 0430
TypeNumber Имплементация протокола Number Protocol Все методы протокола виртуальны и их имплементация по умолчанию вызывает ошибку NotImplementedError 0490
TypeNumberAny То же, что TypeNumber, но допускает операнды произвольного типа 0495
TypeSequence Имплементация протокола Sequence Protocol 0500, 0505
TypeMap Имплементация протокола Mapping Protocol 0510
TypeIterable Имплементация протокола Iterator Protocol 0520

Пример 0850 демонстрирует множественное наследование от нескольких из перечисленных выше классов

TypeBase

Член Описание Примеры
конструктор TypeBase Создает экземпляр TypeBase для типа T и регистрирует его в контейнере. Защищенный, вызывается только потомками. Поскольку все потомки наследуют от TypeBase виртуально, этот конструктор всегда вызывается явно:
TypeBase<T>(@name, @doc)

, где:

  • @name — имя класса в Python-е, уникальное в рамках модуля, строковый литерал, не NULL; не может быть ключевым словом или быть частью маски
  • @doc — описание класса в справке, строковый литерал, допустимо значение NULL
0400, 0410, …
структура T_struct Центральный объект всей библиотеки. Python видит его экземпляры как PyObject *, C++ использует его член endosome — это экземпляр питонизированного класса T. Создается и удаляется как неяно Python-ом так и аллокаторами 0520, 0560
структура argObject Вспомогательная структура, упрощающая использование формата O!, см argObject 0480, 0495, 0505, 0550
allocate, free Создание/удаление структуры T_struct 0560
allocate_static, free_static Статические аналоги allocate и free
address Возвращает адрес объекта T. Синтаксическая конструкция для получения адреса выглядит по-разному при наследовании от TypeWrapper, TypePointer или TypeSmart. Используется трассировщиком, см Container.set_trace_options
constructor Создает экземпляр класса T. Вызывается, когда Python создает новую переменную, связанную с подразумеваемым типом T. Память под объект выделяется Python-ом, поэтому конструктор класса T имеет синтаксис plecement new.

Имплементация по умолчанию — NotImplementedError. Не переопределив этот метод создать T стандартным для Python-а способом не получится

0410, 0460, 0480
destructor Разрушает экземпляр класса T. Вызывается, когда Python уничтожает последнюю переменную, ссылающуюся на объект T. Память из под объекта освобождается Python-ом, поэтому деструктор класса T вызывается явно.

Чисто виртуальный метод

0410, 0460, 0470, 0480
print, repr, str Имплементация функции print, атрибутов __repr__ и __str__ соответственно
static m_get Очевидно, что для каждого типа T должен быть один и только один экземпляр TypeBase<T>, причем доступный из статического контекста. Эту задачу решает статическая переменная внутри статического метода m_get. Установить ее можно единожды, переустановить или использовать неустановленной — невозможно, об этом заботится неперехватываемое исключение TypeInitException 0540, 0910, 0950

TypeWrapper

см описание TypeWrapper

Метод Описание Примеры
address
&T
constructor Наследуется от TypeBase, NotImplementedError 0400, 0410
destructor
Attention.png Нет реализации, чисто виртуальный метод

Типичная реализация:

virtual void destructor(T &obj) const
{
obj.~T();
}
print, repr, str Возвращают имя типа + адрес объекта T
m_add_member Питонизирует поле класса T, при условии, что тип поля входит в таблицу. Использует шаблонные указатели на член данных, пример синтаксиса:
m_add_member<const int, &T::length>(@name, @doc);

, для массивов фиксированного размера:

m_add_member<char[34], &T::message>(@name, @doc);

Первый шаблонный аргумент — тип второго аргумента. Требуется точное соответствие. В противном случае — ошибка компиляции. Второй аргумент — поле, не метод. Параметры:

  • @name — имя поля в Python-е, уникальное в рамках класса, строковый литерал, не NULL; не может быть ключевым словом или быть частью маски
  • @doc — описание поля в справке, строковый литерал, допустимо значение NULL
0440
m_add_method,

m_add_method (const)

Регистрирует метод класса T. Допустимые сигнатуры методов:
void m(const Ptr<T> &, Tuples &) const;
void const_m(const Ptr<const T> &, Tuples &) const;

Если последние реализованы в классе PyType, синтаксис такой:

m_add_method<PyType, &PyType::m>(@name, @help);
m_add_method<PyType, &PyType::const_m>(@name, @help);

, если методы реализованы в PyTypeAncestor, а PyType наследует от него:

m_add_method<PyTypeAncestor, &PyType::m>(@name, @help);
m_add_method<PyTypeAncestor, &PyType::const_m>(@name, @help);

или, что то же:

m_add_method<PyTypeAncestor, &PyTypeAncestor::m>(@name, @help);
m_add_method<PyTypeAncestor, &PyTypeAncestor::const_m>(@name, @help);

, где:

  • @name — имя метода в Python-е, уникальное в рамках класса, строковый литерал, не NULL; не может быть ключевым словом или быть частью маски
  • @help — описание метода в справке, строковый литерал, допустимо значение NULL
0420, 0540, 0940

m_add_method_with_keywords, m_add_method_with_keywords (const)

Аналогично m_add_method, только метод регистрируется с флагом METH_KEYWORDS, благодаря которому его аргументы можно инициализировать по имени 0050
m_add_method_no_args, m_add_method_no_args (const) Аналогично m_add_method, только метод регистрируется с флагом METH_NOARGS и не имеет аргументов
m_add_getter Регистрирует константный метод
void get(const Ptr<const T> &, Tuples &) const

в качестве атрибута только для чтения:

m_add_getter<PyType, &PyType::get>(@name, @help);

Аргументы аналогичны m_add_method

0450, 0455
m_add_setter Регистрирует неконстантный метод
void set(const Ptr<T> &, Tuples &) const

в качестве атрибута только для записи:

m_add_setter<PyType, &PyType::set>(@name, @help);

Аргументы аналогичны m_add_method

m_add_getseter Регистрирует пару методов
void get(const Ptr<const T> &, Tuples &) const
void set(const Ptr<T> &, Tuples &) const

в качестве атрибута "чтение/запись":

m_add_getseter<PyType, &PyType::get, &PyType::set>(@name, @help);

Аргументы аналогичны m_add_method

convert Создает новый экземпляр T_struct копирует в него объект T и преобразует к PyObject с тем, чтобы передать его в Python в качестве возвращаемого значения.

Python владеет этим объектом и как только счетчик ссылок на него обнуляется, вызывает метод destructor, а затем освобождает память из под T_struct

?

TypePointer

см описание TypePointer

Метод Описание Примеры
address
&*pointer<T>
constructor Наследуется от TypeBase, NotImplementedError 0460, 0470
destructor
Attention.png Нет реализации, чисто виртуальный метод

Типичная реализация:

virtual void destructor(pointer<T> &obj) const
{
delete &*obj;
obj.~pointer();
}

Явный вызов деструктора pointer обязателен, хотя и формален

print, repr, str Возвращают имя типа + адрес объекта T
m_add_method, m_add_method (const) Аналогично одноименным методам TypeWrapper 0460
m_add_method_with_keywords, m_add_method_with_keywords(const)
m_add_method_no_args, m_add_method_no_args(const)
m_add_getter
m_add_setter
m_add_getseter
convert Создает новый экземпляр T_struct с указателем на объект T и преобразует его к указателю на PyObject с тем, чтобы передать его в Python в качестве возвращаемого значения.

Python владеет этим объектом и как только счетчик ссылок на него обнуляется, вызывает метод destructor, а затем освобождает память из под T_struct

?

TypeSmart

см описание TypeSmart

Метод Описание Примеры
address Наследуется от TypeWrapper
constructor Наследуется от TypeBase, NotImplementedError 0480
destructor
Attention.png Нет реализации, чисто виртуальный метод
m_add_method, m_add_method (const) Аналогично одноименным методам TypeWrapper. Регистрация наследуемых от TypeWrapper методов требует указания полного имени метода:
TypeWrapper<T>::m_add_method<PyType, &PyType::m>(@name, @help);
m_add_method_with_keywords, m_add_method_with_keywords (const)
m_add_method_no_args, m_add_method_no_args (const)
m_add_getter
m_add_setter
m_add_getseter

TypeSpecial

см описание TypeSpecial

Метод Описание Примеры
address, destructor, print, repr, str
Attention.png Нет реализации, чисто виртуальные методы

Реализацию по умолчанию для всех методов кроме destructor можно позаимствовать от TypeWrapper используя множественное наследование

0430
constructor Наследуется от TypeBase, NotImplementedError
m_add_static_method Регистрирует статический метод класса T со следующей сигнатурой:
static void m(Tuples &);

В предположении, что метод реализован в классе PyType синтаксис такой:

m_add_static_method<&PyType::m>(@name, @help);

Аргументы @name, @help аналогичны TypeWrapper::m_add_method

m_add_static_method_with_keywords Аналогично m_add_static_method только метод регистрируется с флагом METH_KEYWORDS, благодаря которому его аргументы можно инициализировать по имени
m_add_static_method_no_args Аналогично m_add_static_method, только метод регистрируется с флагом METH_NOARGS и не имеет аргументов
m_add_class_method Регистрирует статический метод T со следующей сигнатурой:
static void m(const PyTypeObject &, Tuples &);

в качестве метода класса. В предположении, что метод реализован в классе PyType синтаксис такой:

m_add_class_method<&PyType::m>(@name, @help);

Аргументы @name, @help аналогичны TypeWrapper::m_add_method

m_add_class_method_with_keywords Аналогично m_add_class_method только метод регистрируется с флагом METH_KEYWORDS, благодаря которому его аргументы можно инициализировать по имени 0430
m_add_class_method_no_args Аналогично m_add_static_method, только метод регистрируется с флагом METH_NOARGS и не имеет аргументов

TypeNumber, TypeNumberAny

см описание TypeNumber, TypeNumberAny

Класс TypeNumber требует, чтобы все операнды (а их как правило 2) имели тип T. Класс TypeNumberAny благодаря флагу Py_TPFLAGS_CHECKTYPES допускает, что один из операндов может иметь произвольный тип, а потому все его виртуальные методы питонизированы, см пример 0495

Общие методы

Классы TypeNumber и TypeNumberAny имеют общего предка со следующими методами:

Метод Применение
negative
-x
x.__neg__()
positive
+x
x.__pos__()
absolute
abs(x)
x.__abs__()
nonzero
x != 0
x.__nonzero__()
invert
~x
x.__invert__()
to_long
int(x)
long(x)
x.__int__()
x.__long__()
to_double
float(x)
x.__float__()
to_oct
oct(x)
x.__oct__()
to_hex
hex(x)
x.__hex__()
index
x[y:z]
x[y.__index__():z.__index__()]

Немодифицирующие методы

В отличие от модифицирующих методов Python синтаксис (как правило) состоит из двух операндов, которые не изменяются, знака '=' и результирующего значения — нового объекта. В нижеперечисленных методах первый аргумент (а в методе divmod и второй) является возвращаемым значением и требует вызова конструктора типа T, см примеры 0490, 0495

Метод Применение
TypeNumber TypeNumberAny
add add
x+y
y+x
x.__add__(y)
x.__radd__(y)
subtract subtract
x-y
y-x
x.__sub__(y)
x.__rsub__(y)
multiply multiply
x*y
y*x
x.__mul__(y)
x.__rmul__(y)
divide divide
x/y
y/x
x.__div__(y)
x.__rdiv__(y)
remainder remainder
x%y
y%x
x.__mod__(y)
x.__rmod__(y)
divmod divmod
divmod(x, y)
divmod(y, x)
x.__divmod__(y)
x.__rdivmod__(y)
power, power power
pow(x, y)
pow(x, y, z)
pow(y, x)
pow(y, x, z)
x.__pow__(y)
x.__pow__(y, z)
x.__rpow__(y)
x.__rpow__(y, z)
lshift lshift
x<<y
y<<x
x.__lshift__(y)
x.__rlshift__(y)
rshift rshift
x>>y
y>>x
x.__rshift__(y)
x.__rrshift__(y)
nb_and nb_and
x&y
y&x
x.__and__(y)
x.__rand__(y)
nb_xor nb_xor
x^y
y^x
x.__xor__(y)
x.__rxor__(y)
nb_or nb_or
x|y
y|x
x.__or__(y)
x.__ror__(y)
floor_divide floor_divide
x//y
y//x
x.__floordiv__(y)
x.__rfloordiv__(y)
true_divide true_divide
x/y
y/x
x.__truediv__(y)
x.__rtruediv__(y)

Модифицирующие методы

В отличие от немодифицирующих методов Python синтаксис состоит из двух операндов один из которых изменяется, т. е. является одновременно и аргументом и результатом. Во всех нижеперечисленных методах он является первым параметром, см примеры 0490, 0495

Метод Применение
TypeNumber TypeNumberAny
inplace_add inplace_add
x+=y
x.__iadd__(y)
inplace_subtract inplace_subtract
x-=y
x.__isub__(y)
inplace_multiply inplace_multiply
x*=y
x.__imul__(y)
inplace_divide inplace_divide
x/=y
x.__idiv__(y)
inplace_remainder inplace_remainder
x%=y
x.__imod__(y)
inplace_power,

inplace_power

inplace_power
x**=y
x.__ipow__(y)
inplace_lshift inplace_lshift
x<<=y
x.__ilshift__(y)
inplace_rshift inplace_rshift
x>>=y
x.__irshift__(y)
inplace_and inplace_and
x&=y
x.__iand__(y)
inplace_xor inplace_xor
x^=y
x.__ixor__(y)
inplace_or inplace_or
x|=y
x.__ior__(y)
inplace_floor_divide inplace_floor_divide
x//y
x.__ifloordiv__(y)
inplace_true_divide inplace_true_divide
x/y
x.__itruediv__(y)

TypeSequence

см описание TypeSequence

Методы из первой колонки предъявляют к операндам строгие требования — они должны иметь тип T, см пример 0500, во второй колонке питонизированные аналоги самостоятельно контролируют тип операндов, см пример 0505

Метод Применение
тип операнда:
только T любой
length
len(x)
x.__len__()
concat concat
x+y
x.__add__(y)
concat concat
x+=y
x.__iadd__(y)
repeat
x*=n
repeat
x*n
n*x
get
x[y]
x[i:j]
x.__getitem__(y)
x.__getslice__(i, j)
assign assign
x[i]=y
x[i:j]=y
x.__setitem__(i, y)
x.__setslice__(i, j, y)
del
del x[y]
del x[i:j]
x.__delitem__(y)
x.__delslice__(i, j)
contains contains
y in x
x.__contains__(y)

TypeMap

см описание TypeMap

Все методы, за исключением length питонизированы:

Метод Применение
length
len(x)
x.__len__()
get
x[y]
x.__getitem__(y)
del
del x[y]
x.__delitem__(y)
assign
x[i]=y
x.__setitem__(i, y)

см пример 0510

TypeIterable

см описание TypeIterable

Как правило реализуются два потомка данного класса. В одном реализуется метод iter — он играет роль контейнера, в другом next и он становится собственно итератором, см пример 0520

Метод Применение Примечание
iter
iter(x)
x.__iter__()
Первый аргумент является возвращаемым значением и требует вызова конструктора типа T
next
x.next()

Конвертеры

В макросах питонизации можно использовать произвольный тип данных, если определить для этого типа функцию преобразования в/из PyObject. Задачу упрощают нижеописанные классы (см пример 0100):

Макрос Объект Описание
TupleIn::in_conv_t typedef, указатель на функцию
TupleIn::anything::m_converter Чисто виртуальный метод, осуществляет преобразование из PyObject в произвольные типы. Возвращает 1 при успешном преобразовании, 0 или вызывает std::exception в случае ошибки
PYHROL_PARSE_TUPLE_{M} TupleIn::anything::converter Статическая функция с сигнатурой in_conv_t, становится первым аргументом в паре O&, вызывает TupleIn::anything::m_converter
TupleIn::anything Абстрактный класс, экземпляр его потомка становится вторым аргументом в паре O&
TupleOut::out_conv_t typedef, указатель на функцию
TupleOut::anything::m_converter Чисто виртуальный метод, осуществляет преобразование из произвольного типа в PyObject. Возвращает указатель на PyObject при успешном преобразовании, NULL или вызывает std::exception в случае ошибки
PYHROL_BUILD_VALUE_{N} TupleIn::anything::converter Статическая функция с сигнатурой out_conv_t, становится первым аргументом в паре O&, вызывает TupleOut::anything::m_converter
TupleOut::anything Абстрактный класс, экземпляр его потомка становится вторым аргументом в паре O&

Вспомогательные классы

TypeBase::argObject

Облегчает применение формата O! и помогает избежать ошибок преобразования типа. Пусть класс PyType питонизирует некий тип T. Следующий псевдокод гарантирует:

PyTypeString::argObject arg;
PYHROL_PARSE_TUPLE_{M}(..., arg.cls, arg.pobj, ...)

, что arg будет инициализирован указателем на объект T. Дейсвительно arg.cls имеет тип PyTypeObject, arg.pobj — PyObject, а вместе они — O!. Использовать поле arg.pobj напрямую небезопасно, да и бессмысленно, т. к. в TypeBase::argObject есть удобные операторы обращения к объекту T.

см пример 0550

argString

Преобразует формат s# в std::string и помогает избежать ошибок преобразования типа:

argString arg;
PYHROL_PARSE_TUPLE_{M}(..., arg.data, arg.length, ...)
 
const std::string s = arg;

AutoHolder

Тривиальный блокироввщик ресурсов. Запоминает адрес объекта PyObject от которого каким то образом зависит; конструктор вызывает Py_INCREF на этом объекте, а деструктор — Py_DECREF. Таким образом гарантируется, что пока жив потомок AutoHolder-а, будет жить и используемый им PyObject. Класс слишком прост, чтобы решать насущные практические задачи, например удерживать несколько объектов PyObject. Он используется в примере 0520 но не включен в заголовок pyhrol.h

Container

C++ синглетон. База метаданных. Содержит массив указателей на функции и массив типов из всех загруженных модулей, написанных с применением библиотеки pyhrol. Явный вызов методов этого класса противопоказан (см пример 0930). Методы вызываются из макросов регистрации и из функции pyhrol_init при загрузке модуля.

Частично питонизирован одноименным классом Container

Ptr

Обертка для указателя на объект T. Выполняет следующие функции:

  • Возвращает указатель на объект T. Там, где использование указателя неуместно, возвращает ошибку ValueError, см пример 0925
  • Возвращает указатель на PyObject, соответствующий объекту T в Python-е. Наиболее вероятное применение — управление счетчиками ссылок

Можно видеть практически во всех примерах начиная с 0420

soother

Пустышка. Наследует от TupleIn::anything и ничего не преобразует — m_converter всегда возвращает 1. Используется, например, в имплементации виртуальных методов TypeMap по умолчанию для того, чтобы последние могли вернуть ошибку NotImplementedError невзирая на возможные ошибки преобразования типов аргументов

Tuples

Является неотъемлемой частью большинства питонизированных функций/методов (см сигнатуры). Имплементация данного интерфейса обеспечивает:

  • проверку соответствия реальных аргументов, переданных из Python-а ожидаемым в данной функции/методе
  • упаковку возвращаемого значения
  • сбор метаданных — имен, типов, значений аргументов и возвращаемых значений (только не в режиме PYHROL_SAFE_MODE)
  • обработку ошибок

Из всех методов, объявленных в интерфейсе, интерес представляют только:

Значение, R Описание
R = -1 По умолчанию. Все аргументы обязательны, то же, что requiredAll
R ∈ [0, M) Аргументы начиная c R (нумерация с 0) могут не указываться при вызове из Python. При этом соответствующие C++ переменные должны быть инициализированы, см примеры 0040, 0110, 0120
R >= M То же, что R = -1. В принципе это ошибка, но не перехватывается

, либо перечисляемое значение (см пример 0455):

Значение Описание
optNo По умолчанию. Ничего из нижеперечисленного
optTuple Тип параметра -- tuple, "(форматы)"
optList Результирующий тип -- list, "[ форматы ]", игнорируется в PYHROL_PARSE_TUPLE_{M}
optDictionary Результирующий тип -- dict, "{форматы}", игнорируется в PYHROL_PARSE_TUPLE_{M}
optNoneEnabled Аргументы типа char* могут иметь значение NULL, что соответствует значению None
optIncrementReferenceCount формат N заменяется на O — счетчик ссылок возвращаемого объекта увеличивается на 1;
  • N используется для всех только что созданных объектов
  • O используется для уже существующих объектов, таких как Py_True
optNotRecode формат es заменяется на формат et, а es# на et#

Также есть перегруженная версия, включающая оба вышеупомянутых значения. Параметры, установленные Tuples::set_options учитываются следующим за ним макросом PYHROL_PARSE_TUPLE_{M} или PYHROL_BUILD_VALUE_{N} и тут же сбрасываются на значения по умолчанию.

Остальные методы вызываются неявно через макросы питонизации и не представляют интереса

Исключения (exceptions)

C++ код, что ессно, для обработки ошибок использует иерархию исключений с прародителем std::exception. Python использует иерархию ошибок во главе с BaseException. Эти иерархии сильно отличаются, хотя и имеют много общего или похожего. Однозначного попарного соответствия между ними нет и быть не может.

Pyhrol перехватывает C++ исключения и устанавливает Python ошибку согласно следующей таблице:

C++ Python Описание Примеры
Производные
ImplementationException NotImplementedError Поведение конструктора по умолчанию, большинства методов TypeNumber, TypeNumberAny, TypeSequence, TypeMap, TypeIterable 0400, 0490, 0500
NullPointer ValueError Использование неинициализированного значения в TypePointer или в Ptr 0460, 0925
UseException Вызывается в макросе PYHROL_AFTER_EXECUTE и методе Tuples::parsed_variant 0070, 0920
TupleBaseSafe::FormatException,

TupleBase::FormatException

AttributeError
  • Неверный порядок следования переменных или отсутствие переменной заданного типа в одном из составных типов: es, et, es#, et#, O!, O&, O&
  • Неуникальный список или наличие недопустимых имен аргументов в функции/методе с именованными аргументами
0920
CheckCalls::ForbiddenCall Неверный порядок следования макросов питонизации
ArgsException Теоретически возможны, сценарий изощрен и нечаянно не реализуем
StateException
OverflowException OverflowError
ParseException TypeError Ошибка преобразования типов. Ни один из макросов PYHROL_PARSE_TUPLE_{M} не смог преобразовать PyObject к набору своих аргументов; либо таковых макросов нет, а функция/метод вызывается с аргументами. Типичная ошибка времени исполнения, особенно в интерактивном режиме 0060, 0090, 0455, 0495, 0510, 0550, 0840
Фиктивные
AttributeException AttributeError Используются как общие предки для производных исключений. Могут применяться для имплементации других исключений
KeyException KeyError
TypeException TypeError
Стандартные
ios_base::failure IOError Применение диктуется спецификой приложения
bad_alloc MemoryError
domain_error ValueError
out_of_range LookupError
range_error IndexError
overflow_error OverflowError
runtime_error RuntimeError
exception StandardError
...
Attention.png Исключения, не наследующие от std::exception не перехватываются. Неизлечимо. terminate
TypeInitException
Attention.png Неизлечимо. terminate. Источник m_get
0900, 0910

Справка

Модуль pyhrol

Container

Питонизатор C++ класса Container. Все методы статические:

Имя Описание
is_signature_hack_enabled Управление зондированием, недоступны в режиме PYHROL_SAFE_MODE
enable_signature_hack
disable_signature_hack
get_help_format
get_trace_options
set_help_format
set_trace_options
show_calls
show_index
show_index_names

Метаобъекты

Имя Описание
Function
Functions
FunctionsIterator
Method
Methods
MethodsIterator
Module
Modules
ModulesIterator
Type
Types
TypesIterator
Пространства имён

Варианты
Просмотры
Действия
Навигация