Source code for hpy/inline_helpers.h

#ifndef HPY_INLINE_HELPERS_H
[docs]#define HPY_INLINE_HELPERS_H
#if defined(_MSC_VER) # include <malloc.h> /* for alloca() */ #endif #include <assert.h>
[docs]/** * Same as :c:func:`HPyErr_SetFromErrnoWithFilenameObjects` but passes * ``HPy_NULL`` to the optional arguments. * * :param ctx: * The execution context. * :param h_type: * The exception type to raise. * * :return: * always returns ``HPy_NULL`` */ HPy HPyErr_SetFromErrno(HPyContext *ctx, HPy h_type) { return HPyErr_SetFromErrnoWithFilenameObjects(ctx, h_type, HPy_NULL, HPy_NULL); }
[docs]/** * Same as :c:func:`HPyErr_SetFromErrnoWithFilenameObjects` but passes * ``HPy_NULL`` to the last (optional) argument. * * :param ctx: * The execution context. * :param h_type: * The exception type to raise. * :param filename: * a filename; may be ``HPy_NULL`` * * :return: * always returns ``HPy_NULL`` */ HPy HPyErr_SetFromErrnoWithFilenameObject(HPyContext *ctx, HPy h_type, HPy filename) { return HPyErr_SetFromErrnoWithFilenameObjects(ctx, h_type, filename, HPy_NULL); }
[docs]/** * Create a tuple from arguments. * * A convenience function that will allocate a temporary array of ``HPy`` * elements and use :c:func:`HPyTuple_FromArray` to create a tuple. * * :param ctx: * The execution context. * :param n: * The number of elements to pack into a tuple. * :param ...: * Variable number of ``HPy`` arguments. * * :return: * A new tuple with ``n`` elements or ``HPy_NULL`` in case of an error * occurred. */ HPy HPyTuple_Pack(HPyContext *ctx, HPy_ssize_t n, ...) { va_list vargs; HPy_ssize_t i; if (n == 0) { return HPyTuple_FromArray(ctx, (HPy*)NULL, n); } HPy *array = (HPy *)alloca(n * sizeof(HPy)); va_start(vargs, n); if (array == NULL) { va_end(vargs); return HPy_NULL; } for (i = 0; i < n; i++) { array[i] = va_arg(vargs, HPy); } va_end(vargs); return HPyTuple_FromArray(ctx, array, n); }
[docs]/** * Delete an attribute. * * This is the equivalent of the Python statement ``del o.attr_name``. * * :param ctx: * The execution context. * :param obj: * The object with the attribute. * :param name: * The name (an unicode object) of the attribute. * * :return: * ``0`` on success; ``-1`` in case of an error. */ int HPy_DelAttr(HPyContext *ctx, HPy obj, HPy name) { return HPy_SetAttr(ctx, obj, name, HPy_NULL); }
[docs]/** * Delete an attribute. * * This is the equivalent of the Python statement ``del o.attr_name``. * * :param ctx: * The execution context. * :param obj: * The object with the attribute. * :param utf8_name: * The name (an UTF-8 encoded C string) of the attribute. * * :return: * ``0`` on success; ``-1`` in case of an error. */ int HPy_DelAttr_s(HPyContext *ctx, HPy obj, const char *utf8_name) { return HPy_SetAttr_s(ctx, obj, utf8_name, HPy_NULL); }
[docs]/** * Create a Python long object from a C ``long`` value. * * :param ctx: * The execution context. * :param l: * A C long value. * * :return: * A Python long object with the value of ``l`` or ``HPy_NULL`` on failure. */ HPy HPyLong_FromLong(HPyContext *ctx, long l) { if (sizeof(long) <= sizeof(int32_t)) return HPyLong_FromInt32_t(ctx, (int32_t)l); assert(sizeof(long) <= sizeof(int64_t)); return HPyLong_FromInt64_t(ctx, (int64_t)l); }
[docs]/** * Create a Python long object from a C ``unsigned long`` value. * * :param ctx: * The execution context. * :param l: * A C ``unsigned long`` value. * * :return: * A Python long object with the value of ``l`` or ``HPy_NULL`` on failure. */ HPy HPyLong_FromUnsignedLong(HPyContext *ctx, unsigned long l) { if (sizeof(unsigned long) <= sizeof(uint32_t)) return HPyLong_FromUInt32_t(ctx, (uint32_t)l); assert(sizeof(unsigned long) <= sizeof(uint64_t)); return HPyLong_FromUInt64_t(ctx, (uint64_t)l); }
[docs]/** * Create a Python long object from a C ``long long`` value. * * :param ctx: * The execution context. * :param l: * A C ``long long`` value. * * :return: * A Python long object with the value of ``l`` or ``HPy_NULL`` on failure. */ HPy HPyLong_FromLongLong(HPyContext *ctx, long long l) { assert(sizeof(long long) <= sizeof(int64_t)); return HPyLong_FromInt64_t(ctx, (int64_t)l); }
[docs]/** * Create a Python long object from a C ``unsigned long long`` value. * * :param ctx: * The execution context. * :param l: * A C ``unsigned long long`` value. * * :return: * A Python long object with the value of ``l`` or ``HPy_NULL`` on failure. */ HPy HPyLong_FromUnsignedLongLong(HPyContext *ctx, unsigned long long l) { assert(sizeof(unsigned long long) <= sizeof(uint64_t)); return HPyLong_FromUInt64_t(ctx, (uint64_t)l); }
[docs]/** * Return a C ``long`` representation of the given Python long object. If the * object is not an instance of Python long, the object's ``__index__`` method * (if present) will be used to convert it to a Python long object. * * This function will raise an ``OverflowError`` if the value of the object is * out of range for a C ``long``. * * This function will raise a ``TypeError`` if: * * * The object is neither an instance of Python long nor it provides an * ``__index__`` method. * * If the ``__index__`` method does not return an instance of Python long. * * :param ctx: * The execution context. * :param h: * Either an instance of Python long or an object that provides an * ``__index__`` method (which returns a Python long). * * :return: * A C ``long`` value. Errors will be indicated with return value ``-1``. * In this case, use :c:func:`HPyErr_Occurred` to disambiguate. */ long HPyLong_AsLong(HPyContext *ctx, HPy h) { if (sizeof(long) <= sizeof(int32_t)) return (long) HPyLong_AsInt32_t(ctx, h); else if (sizeof(long) <= sizeof(int64_t)) return (long) HPyLong_AsInt64_t(ctx, h); }
[docs]/** * Return a C ``unsigned long`` representation of the given Python long object. * * This function will raise a ``TypeError`` if the object is not an instance of * Python long and it will raise an ``OverflowError`` if the object's value is * negative or out of range for a C ``unsigned long``. * * :param ctx: * The execution context. * :param h: * The object to convert to C ``unsigned long`` (must be an instance of * Python long). * * :return: * A C ``unsigned long`` value. Errors will be indicated with return value * ``(unsigned long)-1``. In this case, use :c:func:`HPyErr_Occurred` to * disambiguate. */ unsigned long HPyLong_AsUnsignedLong(HPyContext *ctx, HPy h) { if (sizeof(unsigned long) <= sizeof(uint32_t)) return (unsigned long) HPyLong_AsUInt32_t(ctx, h); else if (sizeof(unsigned long) <= sizeof(uint64_t)) return (unsigned long) HPyLong_AsUInt64_t(ctx, h); }
[docs]/** * Return a C ``unsigned long`` representation of the given Python long object. If the * object is not an instance of Python long, the object's ``__index__`` method * (if present) will be used to convert it to a Python long object. * * If the object's value is out of range for an ``unsigned long``, return the * reduction of that value modulo ``ULONG_MAX + 1``. Therefore, this function * will **NOT** raise an ``OverflowError`` if the value of the object is out of * range for a C ``unsigned long``. * * :param ctx: * The execution context. * :param h: * Either an instance of Python long or an object that provides an * ``__index__`` method (which returns a Python long). * * :return: * A C ``unsigned long`` value. Errors will be indicated with return value * ``(unsigned long)-1``. In this case, use :c:func:`HPyErr_Occurred` to * disambiguate. */ unsigned long HPyLong_AsUnsignedLongMask(HPyContext *ctx, HPy h) { if (sizeof(unsigned long) <= sizeof(uint32_t)) return (unsigned long) HPyLong_AsUInt32_tMask(ctx, h); else if (sizeof(unsigned long) <= sizeof(uint64_t)) return (unsigned long) HPyLong_AsUInt64_tMask(ctx, h); }
[docs]/** * Return a C ``long long`` representation of the given Python long object. If * the object is not an instance of Python long, the object's ``__index__`` * method (if present) will be used to convert it to a Python long object. * * This function will raise an ``OverflowError`` if the value of the object is * out of range for a C ``long long``. * * This function will raise a ``TypeError`` if: * * * The object is neither an instance of Python long nor it provides an * ``__index__`` method. * * If the ``__index__`` method does not return an instance of Python long. * * :param ctx: * The execution context. * :param h: * Either an instance of Python long or an object that provides an * ``__index__`` method (which returns a Python long). * * :return: * A C ``long long`` value. Errors will be indicated with return value * ``-1``. In this case, use :c:func:`HPyErr_Occurred` to disambiguate. */ long long HPyLong_AsLongLong(HPyContext *ctx, HPy h) { assert(sizeof(long long) <= sizeof(int64_t)); return (long long) HPyLong_AsInt64_t(ctx, h); }
[docs]/** * Return a C ``unsigned long long`` representation of the given Python long * object. * * This function will raise a ``TypeError`` if the object is not an instance of * Python long and it will raise an ``OverflowError`` if the object's value is * negative or out of range for a C ``unsigned long``. * * :param ctx: * The execution context. * :param h: * The object to convert to C ``unsigned long long`` (must be an instance of * Python long). * * :return: * A C ``unsigned long long`` value. Errors will be indicated with return * value ``(unsigned long long)-1``. In this case, use * :c:func:`HPyErr_Occurred` to disambiguate. */ unsigned long long HPyLong_AsUnsignedLongLong(HPyContext *ctx, HPy h) { assert(sizeof(unsigned long long) <= sizeof(uint64_t)); return (unsigned long long) HPyLong_AsUInt64_t(ctx, h); }
[docs]/** * Return a C ``unsigned long long`` representation of the given Python long * object. If the object is not an instance of Python long, the object's * ``__index__`` method (if present) will be used to convert it to a Python long * object. * * If the object's value is out of range for an ``unsigned long long``, return * the reduction of that value modulo ``ULLONG_MAX + 1``. Therefore, this * function will **NOT** raise an ``OverflowError`` if the value of the object * is out of range for a C ``unsigned long long``. * * :param ctx: * The execution context. * :param h: * Either an instance of Python long or an object that provides an * ``__index__`` method (which returns a Python long). * * :return: * A C ``unsigned long`` value. Errors will be indicated with return value * ``(unsigned long long)-1``. In this case, use :c:func:`HPyErr_Occurred` * to disambiguate. */ unsigned long long HPyLong_AsUnsignedLongLongMask(HPyContext *ctx, HPy h) { assert(sizeof(unsigned long long) <= sizeof(uint64_t)); return (unsigned long long) HPyLong_AsUInt64_tMask(ctx, h); }
[docs]/** * Returns Python ``True`` or ``False`` depending on the truth value of ``v``. * * :param ctx: * The execution context. * :param v: * A C ``long`` value. * * :return: * Python ``True`` if ``v != 0``; Python ``False`` otherwise. */ HPy HPyBool_FromLong(HPyContext *ctx, long v) { return HPyBool_FromBool(ctx, (v ? true : false)); }
[docs]/** * Adjust start/end slice indices assuming a sequence of the specified length. * * Out of bounds indices are clipped in a manner consistent with the handling of * normal slices. This function cannot fail and does not call interpreter * routines. * * :param ctx: * The execution context. * :param length: * The length of the sequence that should be assumed for adjusting the * indices. * :param start: * Pointer to the start value (must not be ``NULL``). * :param stop: * Pointer to the stop value (must not be ``NULL``). * :param step: * The step value of the slice (must not be ``0``) * * :return: * Return the length of the slice. Always successful. Doesn’t call Python code. */ HPy_ssize_t HPySlice_AdjustIndices(HPyContext *_HPy_UNUSED_ARG(ctx), HPy_ssize_t length, HPy_ssize_t *start, HPy_ssize_t *stop, HPy_ssize_t step) { /* Taken from CPython: Written by Jim Hugunin and Chris Chase. */ /* this is harder to get right than you might think */ assert(step != 0); assert(step >= -HPY_SSIZE_T_MAX); if (*start < 0) { *start += length; if (*start < 0) { *start = (step < 0) ? -1 : 0; } } else if (*start >= length) { *start = (step < 0) ? length - 1 : length; } if (*stop < 0) { *stop += length; if (*stop < 0) { *stop = (step < 0) ? -1 : 0; } } else if (*stop >= length) { *stop = (step < 0) ? length - 1 : length; } if (step < 0) { if (*stop < *start) { return (*start - *stop - 1) / (-step) + 1; } } else { if (*start < *stop) { return (*stop - *start - 1) / step + 1; } } return 0; }
[docs]/** * Call a method of a Python object. * * This is a convenience function for calling a method. It uses * :c:func:`HPy_GetAttr_s` and :c:func:`HPy_CallTupleDict` to perform the method * call. * * :param ctx: * The execution context. * :param utf8_name: * The name (UTF-8 encoded C string) of the method. Must not be ``NULL``. * :param receiver: * A handle to the receiver of the call (i.e. the ``self``). Must not be * ``HPy_NULL``. * :param args: * A handle to a tuple containing the positional arguments (must not be * ``HPy_NULL`` but can, of course, be empty). * :param kw: * A handle to a Python dictionary containing the keyword arguments (may be * ``HPy_NULL``). * * :returns: * The result of the call on success, or ``HPy_NULL`` in case of an error. */ HPy HPy_CallMethodTupleDict_s(HPyContext *ctx, const char *utf8_name, HPy receiver, HPy args, HPy kw) { HPy method = HPy_GetAttr_s(ctx, receiver, utf8_name); if (HPy_IsNull(method)) { return HPy_NULL; } HPy result = HPy_CallTupleDict(ctx, method, args, kw); HPy_Close(ctx, method); return result; }
[docs]/** * Call a method of a Python object. * * This is a convenience function for calling a method. It uses * :c:func:`HPy_GetAttr` and :c:func:`HPy_CallTupleDict` to perform the method * call. * * :param ctx: * The execution context. * :param name: * A handle to the name (a Unicode object) of the method. Must not be * ``HPy_NULL``. * :param receiver: * A handle to the receiver of the call (i.e. the ``self``). Must not be * ``HPy_NULL``. * :param args: * A handle to a tuple containing the positional arguments (must not be * ``HPy_NULL`` but can, of course, be empty). * :param kw: * A handle to a Python dictionary containing the keyword arguments (may be * ``HPy_NULL``). * * :returns: * The result of the call on success, or ``HPy_NULL`` in case of an error. */ HPy HPy_CallMethodTupleDict(HPyContext *ctx, HPy name, HPy receiver, HPy args, HPy kw) { HPy method = HPy_GetAttr(ctx, receiver, name); if (HPy_IsNull(method)) { return HPy_NULL; } HPy result = HPy_CallTupleDict(ctx, method, args, kw); HPy_Close(ctx, method); return result; }
#endif //HPY_INLINE_HELPERS_H