Source code for runtime/helpers.c

#include "hpy.h"

[docs]/** * Create a type and add it as an attribute on the given object. The type is * created using :c:func:`HPyType_FromSpec`. The object is often a module that the type * is being added to. * * :param ctx: * The execution context. * :param obj: * A handle to the object the type is being added to (often a module). * :param name: * The name of the attribute on the object to assign the type to. * :param hpyspec: * The type spec to use to create the type. * :param params: * The type spec parameters to use to create the type. * * :returns: ``0`` on failure, ``1`` on success. * * Examples: * * Using ``HPyHelpers_AddType`` without any :c:struct:`HPyType_SpecParam` * parameters: * * .. code-block:: c * * if (!HPyHelpers_AddType(ctx, module, "MyType", hpyspec, NULL)) * return HPy_NULL; * ... * * Using `HPyHelpers_AddType` with `HPyType_SpecParam` parameters: * * .. code-block:: c * * HPyType_SpecParam params[] = { * { HPyType_SpecParam_Base, ctx->h_LongType }, * { 0 } * }; * * if (!HPyHelpers_AddType(ctx, module, "MyType", hpyspec, params)) * return HPy_NULL; * ... */ int HPyHelpers_AddType(HPyContext *ctx, HPy obj, const char *name, HPyType_Spec *hpyspec, HPyType_SpecParam *params) { HPy h_type = HPyType_FromSpec(ctx, hpyspec, params); if (HPy_IsNull(h_type)) { return 0; } if (HPy_SetAttr_s(ctx, obj, name, h_type) != 0) { HPy_Close(ctx, h_type); return 0; } HPy_Close(ctx, h_type); return 1; }
[docs]/** * Convert positional/keyword argument vector to argument tuple and keywords * dictionary. * * This helper function is useful to convert arguments from HPy's calling * convention to the legacy CPython *tp_call* calling convention. HPy's calling * convention is similar to CPython's fastcall/vectorcall calling convention * where positional and keyword arguments are passed as a C array, the number of * positional arguments is explicitly given by an argument and the names of the * keyword arguments are provided in a tuple. * * For an example on how to use this function, see section * :ref:`call-migration`. * * :param ctx: * The execution context. * :param args: * A pointer to an array of positional and keyword arguments. This argument * must not be ``NULL`` if ``nargs > 0`` or * ``HPy_Length(ctx, kwnames) > 0``. * :param nargs: * The number of positional arguments in ``args``. * :param kwnames: * A handle to the tuple of keyword argument names (may be ``HPy_NULL``). * The values of the keyword arguments are also passed in ``args`` appended * to the positional arguments. Argument ``nargs`` does not include the * keyword argument count. * :param out_pos_args: * A pointer to a variable where to write the created positional arguments * tuple to. If there are no positional arguments (i.e. ``nargs == 0``), * then ``HPy_NULL`` will be written. The pointer will not be used if any * error occurs during conversion. * :param out_kwd: * A pointer to a variable where to write the created keyword arguments * dictionary to. If there are not keyword arguments (i.e. * ``HPy_Length(ctx, kwnames) == 0``), then ``HPy_NULL`` will be written. * The pointer will not be used if any error occurs during conversion. * * :returns: ``0`` on failure, ``1`` on success. */ int HPyHelpers_PackArgsAndKeywords(HPyContext *ctx, const HPy *args, size_t nargs, HPy kwnames, HPy *out_pos_args, HPy *out_kwd) { HPy pos_args, kwd, tmp; HPy_ssize_t nkw, i; if (out_pos_args == NULL) { HPyErr_SetString(ctx, ctx->h_SystemError, "argument 'out_pos_args' must not be NULL"); return 0; } if (out_kwd == NULL) { HPyErr_SetString(ctx, ctx->h_SystemError, "argument 'out_kwd' must not be NULL"); return 0; } nkw = HPy_IsNull(kwnames) ? 0 : HPy_Length(ctx, kwnames); if (nkw < 0) { return 0; } else if (nkw > 0) { kwd = HPyDict_New(ctx); for (i=0; i < nkw; i++) { tmp = HPy_GetItem_i(ctx, kwnames, i); if (HPy_IsNull(tmp)) { HPy_Close(ctx, kwd); return 0; } if (HPy_SetItem(ctx, kwd, tmp, args[nargs + i]) < 0) { HPy_Close(ctx, tmp); HPy_Close(ctx, kwd); return 0; } HPy_Close(ctx, tmp); } } else { assert(nkw == 0); kwd = HPy_NULL; } if (nargs > 0) { pos_args = HPyTuple_FromArray(ctx, (HPy *)args, nargs); if (HPy_IsNull(pos_args)) { HPy_Close(ctx, kwd); return 0; } } else { pos_args = HPy_NULL; } // only write to output variables if everything was successful *out_pos_args = pos_args; *out_kwd = kwd; return 1; }