Cleanup: move public doc-strings into headers for 'python'

This commit is contained in:
Campbell Barton 2021-12-02 17:24:04 +11:00
parent 1766549418
commit 42a6b2fd06
44 changed files with 290 additions and 277 deletions

View File

@ -55,7 +55,13 @@ int BPY_is_pyconstraint(struct Text *text);
typedef void *BPy_ThreadStatePtr;
/**
* Analogue of #PyEval_SaveThread()
*/
BPy_ThreadStatePtr BPY_thread_save(void);
/**
* Analogue of #PyEval_RestoreThread()
*/
void BPY_thread_restore(BPy_ThreadStatePtr tstate);
/* our own wrappers to Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS */
@ -74,7 +80,18 @@ void BPY_modules_load_user(struct bContext *C);
void BPY_app_handlers_reset(const short do_all);
/**
* Update function, it gets rid of py-drivers global dictionary, forcing
* BPY_driver_exec to recreate it. This function is used to force
* reloading the Blender text module "pydrivers.py", if available, so
* updates in it reach py-driver evaluation.
*/
void BPY_driver_reset(void);
/**
* This evaluates Python driver expressions, `driver_orig->expression`
* is a Python expression that should evaluate to a float number, which is returned.
*/
float BPY_driver_exec(struct PathResolvedRNA *anim_rna,
struct ChannelDriver *driver,
struct ChannelDriver *driver_orig,
@ -93,6 +110,16 @@ void BPY_context_update(struct bContext *C);
(C)->data.py_context_orig, \
((const char *[]){__VA_ARGS__}), \
VA_NARGS_COUNT(__VA_ARGS__))
/**
* Use for `CTX_*_set(..)` functions need to set values which are later read back as expected.
* In this case we don't want the Python context to override the values as it causes problems
* see T66256.
*
* \param dict_p: A pointer to #bContext.data.py_context so we can assign a new value.
* \param dict_orig: The value of #bContext.data.py_context_orig to check if we need to copy.
*
* \note Typically accessed via #BPY_context_dict_clear_members macro.
*/
void BPY_context_dict_clear_members_array(void **dict_p,
void *dict_orig,
const char *context_members[],

View File

@ -745,9 +745,6 @@ static PyObject *bpy_slot_to_py(BMesh *bm, BMOpSlot *slot)
return item;
}
/**
* This is the __call__ for bmesh.ops.xxx()
*/
PyObject *BPy_BMO_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *kw)
{
PyObject *ret;

View File

@ -28,4 +28,7 @@ typedef struct {
const char *opname;
} BPy_BMeshOpFunc;
/**
* This is the `__call__` for `bmesh.ops.xxx()`.
*/
PyObject *BPy_BMO_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *kw);

View File

@ -3954,7 +3954,6 @@ PyObject *BPy_BMIter_CreatePyObject(BMesh *bm)
return (PyObject *)self;
}
/* this is just a helper func */
PyObject *BPy_BMElem_CreatePyObject(BMesh *bm, BMHeader *ele)
{
switch (ele->htype) {
@ -4036,11 +4035,6 @@ void bpy_bm_generic_invalidate(BPy_BMGeneric *self)
self->bm = NULL;
}
/* generic python seq as BMVert/Edge/Face array,
* return value must be freed with PyMem_FREE(...);
*
* The 'bm_r' value is assigned when empty, and used when set.
*/
void *BPy_BMElem_PySeq_As_Array_FAST(BMesh **r_bm,
PyObject *seq_fast,
Py_ssize_t min,
@ -4233,11 +4227,6 @@ int BPy_BMElem_CheckHType(PyTypeObject *type, const char htype)
((htype & BM_LOOP) && (type == &BPy_BMLoop_Type)));
}
/**
* Use for error strings only, not thread safe,
*
* \return a string like '(BMVert/BMEdge/BMFace/BMLoop)'
*/
char *BPy_BMElem_StringFromHType_ex(const char htype, char ret[32])
{
/* zero to ensure string is always NULL terminated */

View File

@ -148,9 +148,15 @@ PyObject *BPy_BMFaceSeq_CreatePyObject(BMesh *bm);
PyObject *BPy_BMLoopSeq_CreatePyObject(BMesh *bm);
PyObject *BPy_BMIter_CreatePyObject(BMesh *bm);
/* Just checks type and creates v/e/f/l. */
/** Just checks type and creates vert/edge/face/loop. */
PyObject *BPy_BMElem_CreatePyObject(BMesh *bm, BMHeader *ele);
/**
* Generic python seq as BMVert/Edge/Face array,
* return value must be freed with PyMem_FREE(...);
*
* The 'bm_r' value is assigned when empty, and used when set.
*/
void *BPy_BMElem_PySeq_As_Array_FAST(BMesh **r_bm,
PyObject *seq_fast,
Py_ssize_t min,
@ -177,6 +183,11 @@ PyObject *BPy_BMFace_Array_As_Tuple(BMesh *bm, BMFace **elem, Py_ssize_t elem_le
PyObject *BPy_BMLoop_Array_As_Tuple(BMesh *bm, BMLoop **elem, Py_ssize_t elem_len);
int BPy_BMElem_CheckHType(PyTypeObject *type, const char htype);
/**
* Use for error strings only, not thread safe,
*
* \return a string like '(BMVert/BMEdge/BMFace/BMLoop)'
*/
char *BPy_BMElem_StringFromHType_ex(const char htype, char ret[32]);
char *BPy_BMElem_StringFromHType(const char htype);
@ -198,7 +209,9 @@ int bpy_bm_generic_valid_check_source(BMesh *bm_source,
} \
(void)0
/* macros like BPY_BM_CHECK_OBJ/BPY_BM_CHECK_INT that ensure we're from the right BMesh */
/**
* Macros like `BPY_BM_CHECK_OBJ/BPY_BM_CHECK_INT` that ensure we're from the right #BMesh.
*/
#define BPY_BM_CHECK_SOURCE_OBJ(bm, errmsg, ...) \
{ \
void *_args[] = {__VA_ARGS__}; \

View File

@ -1104,13 +1104,6 @@ static void *bpy_bmlayeritem_ptr_get(BPy_BMElem *py_ele, BPy_BMLayerItem *py_lay
return value;
}
/**
*\brief BMElem.__getitem__()
*
* assume all error checks are done, eg:
*
* uv = vert[uv_layer]
*/
PyObject *BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer)
{
void *value = bpy_bmlayeritem_ptr_get(py_ele, py_layer);

View File

@ -23,7 +23,8 @@
#pragma once
/* all use BPy_BMLayerAccess struct */
/* All use #BPy_BMLayerAccess struct. */
extern PyTypeObject BPy_BMLayerAccessVert_Type;
extern PyTypeObject BPy_BMLayerAccessEdge_Type;
extern PyTypeObject BPy_BMLayerAccessFace_Type;
@ -36,14 +37,14 @@ extern PyTypeObject BPy_BMLayerItem_Type;
#define BPy_BMLayerCollection_Check(v) (Py_TYPE(v) == &BPy_BMLayerCollection_Type)
#define BPy_BMLayerItem_Check(v) (Py_TYPE(v) == &BPy_BMLayerItem_Type)
/* all layers for vert/edge/face/loop */
/** All layers for vert/edge/face/loop. */
typedef struct BPy_BMLayerAccess {
PyObject_VAR_HEAD
struct BMesh *bm; /* keep first */
char htype;
} BPy_BMLayerAccess;
/* access different layer types deform/uv/vertexcolor */
/** Access different layer types deform/uv/vertex-color. */
typedef struct BPy_BMLayerCollection {
PyObject_VAR_HEAD
struct BMesh *bm; /* keep first */
@ -51,7 +52,7 @@ typedef struct BPy_BMLayerCollection {
int type; /* customdata type - CD_XXX */
} BPy_BMLayerCollection;
/* access a specific layer directly */
/** Access a specific layer directly. */
typedef struct BPy_BMLayerItem {
PyObject_VAR_HEAD
struct BMesh *bm; /* keep first */
@ -66,6 +67,10 @@ PyObject *BPy_BMLayerItem_CreatePyObject(BMesh *bm, const char htype, int type,
void BPy_BM_init_types_customdata(void);
/* __getitem__ / __setitem__ */
/**
*\brief BMElem.__getitem__() / __setitem__()
*
* Assume all error checks are done, eg: `uv = vert[uv_layer]`
*/
PyObject *BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer);
int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObject *value);

View File

@ -683,7 +683,6 @@ PyObject *BPy_BMDeformVert_CreatePyObject(struct MDeformVert *dvert)
/* --- End Mesh Deform Vert --- */
/* call to init all types */
void BPy_BM_init_types_meshdata(void)
{
bm_init_types_bmloopuv();

View File

@ -50,4 +50,5 @@ PyObject *BPy_BMLoopColor_CreatePyObject(struct MLoopCol *mloopcol);
int BPy_BMDeformVert_AssignPyObject(struct MDeformVert *dvert, PyObject *value);
PyObject *BPy_BMDeformVert_CreatePyObject(struct MDeformVert *dvert);
/* call to init all types */
void BPy_BM_init_types_meshdata(void);

View File

@ -411,9 +411,6 @@ void BPy_BM_init_types_select(void)
/* utility function */
/**
* \note doesn't actually check selection.
*/
int BPy_BMEditSel_Assign(BPy_BMesh *self, PyObject *value)
{
BMesh *bm;

View File

@ -46,4 +46,7 @@ void BPy_BM_init_types_select(void);
PyObject *BPy_BMEditSel_CreatePyObject(BMesh *bm);
PyObject *BPy_BMEditSelIter_CreatePyObject(BMesh *bm);
/**
* \note doesn't actually check selection.
*/
int BPy_BMEditSel_Assign(struct BPy_BMesh *self, PyObject *value);

View File

@ -666,13 +666,6 @@ static Buffer *BGL_MakeBuffer_FromData(
return buffer;
}
/**
* Create a buffer object
*
* \param dimensions: An array of ndimensions integers representing the size of each dimension.
* \param initbuffer: When not NULL holds a contiguous buffer
* with the correct format from which the buffer will be initialized
*/
Buffer *BGL_MakeBuffer(int type, int ndimensions, int *dimensions, void *initbuffer)
{
Buffer *buffer;

View File

@ -22,6 +22,13 @@
PyObject *BPyInit_bgl(void);
/**
* Create a buffer object
*
* \param dimensions: An array of ndimensions integers representing the size of each dimension.
* \param initbuffer: When not NULL holds a contiguous buffer
* with the correct format from which the buffer will be initialized
*/
struct _Buffer *BGL_MakeBuffer(int type, int ndimensions, int *dimensions, void *initbuffer);
int BGL_typeSize(int type);
@ -50,5 +57,5 @@ typedef struct _Buffer {
} buf;
} Buffer;
/** The type object */
/** The type object. */
extern PyTypeObject BGL_bufferType;

View File

@ -26,7 +26,6 @@
#include "../BPY_extern.h"
#include "BLI_utildefines.h"
/* analogue of PyEval_SaveThread() */
BPy_ThreadStatePtr BPY_thread_save(void)
{
/* Use `_PyThreadState_UncheckedGet()` instead of `PyThreadState_Get()`, to avoid a fatal error
@ -40,7 +39,6 @@ BPy_ThreadStatePtr BPY_thread_save(void)
return NULL;
}
/* analogue of PyEval_RestoreThread() */
void BPY_thread_restore(BPy_ThreadStatePtr tstate)
{
if (tstate) {

View File

@ -686,12 +686,6 @@ static IDProperty *idp_from_PyObject(PyObject *name_obj, PyObject *ob)
/** \name Mapping Get/Set (Internal Access)
* \{ */
/**
* \note group can be a pointer array or a group.
* assume we already checked key is a string.
*
* \return success.
*/
bool BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty *group, PyObject *ob)
{
IDProperty *prop = idp_from_PyObject(name_obj, ob);
@ -779,7 +773,6 @@ static PyObject *BPy_IDGroup_iter(BPy_IDProperty *self)
return BPy_IDGroup_ViewKeys_CreatePyObject(self);
}
/* for simple, non nested types this is the same as BPy_IDGroup_WrapData */
PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop)
{
switch (prop->type) {

View File

@ -95,8 +95,17 @@ PyObject *BPy_Wrap_GetItems_View_WithID(struct ID *id, struct IDProperty *prop);
int BPy_Wrap_SetMapItem(struct IDProperty *prop, PyObject *key, PyObject *val);
/**
* For simple, non nested types this is the same as #BPy_IDGroup_WrapData.
*/
PyObject *BPy_IDGroup_MapDataToPy(struct IDProperty *prop);
PyObject *BPy_IDGroup_WrapData(struct ID *id, struct IDProperty *prop, struct IDProperty *parent);
/**
* \note group can be a pointer array or a group.
* assume we already checked key is a string.
*
* \return success.
*/
bool BPy_IDProperty_Map_ValidateAndCreate(PyObject *key, struct IDProperty *group, PyObject *ob);
void IDProp_Init_Types(void);

View File

@ -41,10 +41,6 @@
/** \name Enum Utilities
* \{ */
/**
* Convert all items into a single comma separated string.
* Use for creating useful error messages.
*/
char *pyrna_enum_repr(const EnumPropertyItem *item)
{
DynStr *dynstr = BLI_dynstr_new();
@ -69,9 +65,6 @@ char *pyrna_enum_repr(const EnumPropertyItem *item)
/** \name Enum Conversion Utilities
* \{ */
/**
* Same as #RNA_enum_value_from_id, but raises an exception.
*/
int pyrna_enum_value_from_id(const EnumPropertyItem *item,
const char *identifier,
int *r_value,
@ -88,14 +81,6 @@ int pyrna_enum_value_from_id(const EnumPropertyItem *item,
return 0;
}
/**
* Takes a set of strings and map it to and array of booleans.
*
* Useful when the values aren't flags.
*
* \param type_convert_sign: Maps signed to unsigned range,
* needed when we want to use the full range of a signed short/char.
*/
BLI_bitmap *pyrna_enum_bitmap_from_set(const EnumPropertyItem *items,
PyObject *value,
int type_size,
@ -159,9 +144,6 @@ error:
return NULL;
}
/**
* 'value' _must_ be a set type, error check before calling.
*/
int pyrna_enum_bitfield_from_set(const EnumPropertyItem *items,
PyObject *value,
int *r_value,
@ -223,9 +205,6 @@ PyObject *pyrna_enum_bitfield_as_set(const EnumPropertyItem *items, int value)
/** \name Argument Parsing Helpers
* \{ */
/**
* Use with #PyArg_ParseTuple's `O&` formatting.
*/
int pyrna_enum_value_parse_string(PyObject *o, void *p)
{
const char *identifier = PyUnicode_AsUTF8(o);
@ -244,9 +223,6 @@ int pyrna_enum_value_parse_string(PyObject *o, void *p)
return 1;
}
/**
* Use with #PyArg_ParseTuple's `O&` formatting.
*/
int pyrna_enum_bitfield_parse_set(PyObject *o, void *p)
{
if (!PySet_Check(o)) {

View File

@ -25,13 +25,28 @@
struct EnumPropertyItem;
/**
* Convert all items into a single comma separated string.
* Use for creating useful error messages.
*/
char *pyrna_enum_repr(const struct EnumPropertyItem *item);
/**
* Same as #RNA_enum_value_from_id, but raises an exception.
*/
int pyrna_enum_value_from_id(const struct EnumPropertyItem *item,
const char *identifier,
int *value,
const char *error_prefix);
/**
* Takes a set of strings and map it to and array of booleans.
*
* Useful when the values aren't flags.
*
* \param type_convert_sign: Maps signed to unsigned range,
* needed when we want to use the full range of a signed short/char.
*/
unsigned int *pyrna_enum_bitmap_from_set(const struct EnumPropertyItem *items,
PyObject *value,
int type_size,
@ -39,6 +54,9 @@ unsigned int *pyrna_enum_bitmap_from_set(const struct EnumPropertyItem *items,
int bitmap_size,
const char *error_prefix);
/**
* 'value' _must_ be a set type, error check before calling.
*/
int pyrna_enum_bitfield_from_set(const struct EnumPropertyItem *items,
PyObject *value,
int *r_value,
@ -62,5 +80,11 @@ struct BPy_EnumProperty_Parse {
int value;
bool is_set;
};
/**
* Use with #PyArg_ParseTuple's `O&` formatting.
*/
int pyrna_enum_value_parse_string(PyObject *o, void *p);
/**
* Use with #PyArg_ParseTuple's `O&` formatting.
*/
int pyrna_enum_bitfield_parse_set(PyObject *o, void *p);

View File

@ -470,10 +470,6 @@ PyObject *PyC_Tuple_PackArray_Multi_Bool(const bool *array, const int dims[], co
/** \name Tuple/List Filling
* \{ */
/**
* Caller needs to ensure tuple is uninitialized.
* Handy for filling a tuple with None for eg.
*/
void PyC_Tuple_Fill(PyObject *tuple, PyObject *value)
{
const uint tot = PyTuple_GET_SIZE(tuple);
@ -502,11 +498,6 @@ void PyC_List_Fill(PyObject *list, PyObject *value)
/** \name Bool/Enum Argument Parsing
* \{ */
/**
* Use with PyArg_ParseTuple's "O&" formatting.
*
* \see #PyC_Long_AsBool for a similar function to use outside of argument parsing.
*/
int PyC_ParseBool(PyObject *o, void *p)
{
bool *bool_p = p;
@ -520,9 +511,6 @@ int PyC_ParseBool(PyObject *o, void *p)
return 1;
}
/**
* Use with PyArg_ParseTuple's "O&" formatting.
*/
int PyC_ParseStringEnum(PyObject *o, void *p)
{
struct PyC_StringEnum *e = p;
@ -598,10 +586,6 @@ void PyC_ObSpit(const char *name, PyObject *var)
}
}
/**
* A version of #PyC_ObSpit that writes into a string (and doesn't take a name argument).
* Use for logging.
*/
void PyC_ObSpitStr(char *result, size_t result_len, PyObject *var)
{
/* No name, creator of string can manage that. */
@ -789,13 +773,6 @@ PyObject *PyC_FrozenSetFromStrings(const char **strings)
/** \name Exception Utilities
* \{ */
/**
* Similar to #PyErr_Format(),
*
* Implementation - we can't actually prepend the existing exception,
* because it could have _any_ arguments given to it, so instead we get its
* `__str__` output and raise our own exception including it.
*/
PyObject *PyC_Err_Format_Prefix(PyObject *exception_type_prefix, const char *format, ...)
{
PyObject *error_value_prefix;
@ -835,10 +812,6 @@ PyObject *PyC_Err_SetString_Prefix(PyObject *exception_type_prefix, const char *
return PyC_Err_Format_Prefix(exception_type_prefix, "%s", str);
}
/**
* Use for Python callbacks run directly from C,
* when we can't use normal methods of raising exceptions.
*/
void PyC_Err_PrintWithFunc(PyObject *py_func)
{
/* since we return to C code we can't leave the error */
@ -1014,7 +987,6 @@ PyObject *PyC_ExceptionBuffer_Simple(void)
* In some cases we need to coerce strings, avoid doing this inline.
* \{ */
/* string conversion, escape non-unicode chars, coerce must be set to NULL */
const char *PyC_UnicodeAsByteAndSize(PyObject *py_str, Py_ssize_t *size, PyObject **coerce)
{
const char *result;
@ -1093,18 +1065,6 @@ PyObject *PyC_UnicodeFromByte(const char *str)
/** \name Name Space Creation/Manipulation
* \{ */
/*****************************************************************************
* Description: This function creates a new Python dictionary object.
* NOTE: dict is owned by sys.modules["__main__"] module, reference is borrowed
* NOTE: important we use the dict from __main__, this is what python expects
* for 'pickle' to work as well as strings like this...
* >> foo = 10
* >> print(__import__("__main__").foo)
*
* NOTE: this overwrites __main__ which gives problems with nested calls.
* be sure to run PyC_MainModule_Backup & PyC_MainModule_Restore if there is
* any chance that python is in the call stack.
****************************************************************************/
PyObject *PyC_DefaultNameSpace(const char *filename)
{
PyObject *modules = PyImport_GetModuleDict();
@ -1143,7 +1103,6 @@ bool PyC_NameSpace_ImportArray(PyObject *py_dict, const char *imports[])
return true;
}
/* restore MUST be called after this */
void PyC_MainModule_Backup(PyObject **r_main_mod)
{
PyObject *modules = PyImport_GetModuleDict();
@ -1468,11 +1427,6 @@ PyObject *PyC_FlagSet_FromBitfield(PyC_FlagSet *items, int flag)
/** \name Run String (Evaluate to Primitive Types)
* \{ */
/**
* \return success
*
* \note it is caller's responsibility to acquire & release GIL!
*/
bool PyC_RunString_AsNumber(const char *imports[],
const char *expr,
const char *filename,
@ -1648,32 +1602,6 @@ bool PyC_RunString_AsString(const char *imports[],
# pragma GCC diagnostic ignored "-Wtype-limits"
#endif
/**
*
* Comparison with #PyObject_IsTrue
* ================================
*
* Even though Python provides a way to retrieve the boolean value for an object,
* in many cases it's far too relaxed, with the following examples coercing values.
*
* \code{.py}
* data.value = "Text" # True.
* data.value = "" # False.
* data.value = {1, 2} # True
* data.value = {} # False.
* data.value = None # False.
* \endcode
*
* In practice this is often a mistake by the script author that doesn't behave as they expect.
* So it's better to be more strict for attribute assignment and function arguments,
* only accepting True/False 0/1.
*
* If coercing a value is desired, it can be done explicitly: `data.value = bool(value)`
*
* \see #PyC_ParseBool for use with #PyArg_ParseTuple and related functions.
*
* \note Don't use `bool` return type, so -1 can be used as an error value.
*/
int PyC_Long_AsBool(PyObject *value)
{
const int test = _PyLong_AsInt(value);

View File

@ -26,6 +26,10 @@
#include "BLI_utildefines_variadic.h"
void PyC_ObSpit(const char *name, PyObject *var);
/**
* A version of #PyC_ObSpit that writes into a string (and doesn't take a name argument).
* Use for logging.
*/
void PyC_ObSpitStr(char *result, size_t result_len, PyObject *var);
void PyC_LineSpit(void);
void PyC_StackSpit(void);
@ -34,9 +38,20 @@ PyObject *PyC_ExceptionBuffer_Simple(void);
PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...);
PyObject *PyC_FrozenSetFromStrings(const char **strings);
/**
* Similar to #PyErr_Format(),
*
* Implementation - we can't actually prepend the existing exception,
* because it could have _any_ arguments given to it, so instead we get its
* `__str__` output and raise our own exception including it.
*/
PyObject *PyC_Err_Format_Prefix(PyObject *exception_type_prefix, const char *format, ...);
PyObject *PyC_Err_SetString_Prefix(PyObject *exception_type_prefix, const char *str);
/**
* Use for Python callbacks run directly from C,
* when we can't use normal methods of raising exceptions.
*/
void PyC_Err_PrintWithFunc(PyObject *py_func);
void PyC_FileAndNum(const char **r_filename, int *r_lineno);
@ -92,6 +107,10 @@ PyObject *PyC_Tuple_PackArray_Multi_F64(const double *array, const int dims[], c
PyObject *PyC_Tuple_PackArray_Multi_I32(const int *array, const int dims[], const int dims_len);
PyObject *PyC_Tuple_PackArray_Multi_Bool(const bool *array, const int dims[], const int dims_len);
/**
* Caller needs to ensure tuple is uninitialized.
* Handy for filling a tuple with None for eg.
*/
void PyC_Tuple_Fill(PyObject *tuple, PyObject *value);
void PyC_List_Fill(PyObject *list, PyObject *value);
@ -99,13 +118,31 @@ void PyC_List_Fill(PyObject *list, PyObject *value);
PyObject *PyC_UnicodeFromByte(const char *str);
PyObject *PyC_UnicodeFromByteAndSize(const char *str, Py_ssize_t size);
const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce); /* coerce must be NULL */
/**
* String conversion, escape non-unicode chars
* \param coerce: must be set to NULL.
*/
const char *PyC_UnicodeAsByteAndSize(PyObject *py_str, Py_ssize_t *size, PyObject **coerce);
/* name namespace function for bpy */
/**
* Description: This function creates a new Python dictionary object.
* NOTE: dict is owned by sys.modules["__main__"] module, reference is borrowed
* NOTE: important we use the dict from __main__, this is what python expects
* for 'pickle' to work as well as strings like this...
* >> foo = 10
* >> print(__import__("__main__").foo)
*
* NOTE: this overwrites __main__ which gives problems with nested calls.
* be sure to run PyC_MainModule_Backup & PyC_MainModule_Restore if there is
* any chance that python is in the call stack.
*/
PyObject *PyC_DefaultNameSpace(const char *filename);
void PyC_RunQuicky(const char *filepath, int n, ...);
bool PyC_NameSpace_ImportArray(PyObject *py_dict, const char *imports[]);
/**
* #PyC_MainModule_Restore MUST be called after #PyC_MainModule_Backup.
*/
void PyC_MainModule_Backup(PyObject **r_main_mod);
void PyC_MainModule_Restore(PyObject *main_mod);
@ -131,6 +168,11 @@ int PyC_FlagSet_ToBitfield(const PyC_FlagSet *items,
const char *error_prefix);
PyObject *PyC_FlagSet_FromBitfield(PyC_FlagSet *items, int flag);
/**
* \return success
*
* \note it is caller's responsibility to acquire & release GIL!
*/
bool PyC_RunString_AsNumber(const char **imports,
const char *expr,
const char *filename,
@ -149,6 +191,11 @@ bool PyC_RunString_AsString(const char **imports,
const char *filename,
char **r_value);
/**
* Use with PyArg_ParseTuple's "O&" formatting.
*
* \see #PyC_Long_AsBool for a similar function to use outside of argument parsing.
*/
int PyC_ParseBool(PyObject *o, void *p);
struct PyC_StringEnumItems {
@ -160,6 +207,9 @@ struct PyC_StringEnum {
int value_found;
};
/**
* Use with PyArg_ParseTuple's "O&" formatting.
*/
int PyC_ParseStringEnum(PyObject *o, void *p);
const char *PyC_StringEnum_FindIDFromValue(const struct PyC_StringEnumItems *items,
const int value);
@ -167,6 +217,32 @@ const char *PyC_StringEnum_FindIDFromValue(const struct PyC_StringEnumItems *ite
int PyC_CheckArgs_DeepCopy(PyObject *args);
/* Integer parsing (with overflow checks), -1 on error. */
/**
*
* Comparison with #PyObject_IsTrue
* ================================
*
* Even though Python provides a way to retrieve the boolean value for an object,
* in many cases it's far too relaxed, with the following examples coercing values.
*
* \code{.py}
* data.value = "Text" # True.
* data.value = "" # False.
* data.value = {1, 2} # True
* data.value = {} # False.
* data.value = None # False.
* \endcode
*
* In practice this is often a mistake by the script author that doesn't behave as they expect.
* So it's better to be more strict for attribute assignment and function arguments,
* only accepting True/False 0/1.
*
* If coercing a value is desired, it can be done explicitly: `data.value = bool(value)`
*
* \see #PyC_ParseBool for use with #PyArg_ParseTuple and related functions.
*
* \note Don't use `bool` return type, so -1 can be used as an error value.
*/
int PyC_Long_AsBool(PyObject *value);
int8_t PyC_Long_AsI8(PyObject *value);
int16_t PyC_Long_AsI16(PyObject *value);

View File

@ -36,16 +36,20 @@ extern "C" {
} \
(void)0
/* wrap Py_INCREF & return the result,
* use sparingly to avoid comma operator or temp var assignment */
/**
* Wrap #Py_INCREF & return the result,
* use sparingly to avoid comma operator or temp var assignment.
*/
Py_LOCAL_INLINE(PyObject *) Py_INCREF_RET(PyObject *op)
{
Py_INCREF(op);
return op;
}
/* Append & transfer ownership to the list,
* avoids inline Py_DECREF all over (which is quite a large macro). */
/**
* Append & transfer ownership to the list,
* avoids inline #Py_DECREF all over (which is quite a large macro).
*/
Py_LOCAL_INLINE(int) PyList_APPEND(PyObject *op, PyObject *v)
{
int ret = PyList_Append(op, v);

View File

@ -687,13 +687,6 @@ size_t bpygpu_Buffer_size(BPyGPUBuffer *buffer)
return pygpu_buffer_calc_size(buffer->format, buffer->shape_len, buffer->shape);
}
/**
* Create a buffer object
*
* \param shape: An array of `shape_len` integers representing the size of each dimension.
* \param buffer: When not NULL holds a contiguous buffer
* with the correct format from which the buffer will be initialized
*/
BPyGPUBuffer *BPyGPU_Buffer_CreatePyObject(const int format,
const Py_ssize_t *shape,
const int shape_len,

View File

@ -48,6 +48,13 @@ typedef struct BPyGPUBuffer {
} BPyGPUBuffer;
size_t bpygpu_Buffer_size(BPyGPUBuffer *buffer);
/**
* Create a buffer object
*
* \param shape: An array of `shape_len` integers representing the size of each dimension.
* \param buffer: When not NULL holds a contiguous buffer
* with the correct format from which the buffer will be initialized
*/
BPyGPUBuffer *BPyGPU_Buffer_CreatePyObject(const int format,
const Py_ssize_t *shape,
const int shape_len,

View File

@ -450,9 +450,6 @@ static PyObject *bpy_import_test(const char *modname)
return mod;
}
/******************************************************************************
* Description: Creates the bpy module and adds it to sys.modules for importing
******************************************************************************/
void BPy_init_modules(struct bContext *C)
{
PointerRNA ctx_ptr;

View File

@ -26,7 +26,9 @@ extern "C" {
struct bContext;
/** Creates the bpy module and adds it to `sys.modules` for importing. */
void BPy_init_modules(struct bContext *C);
extern PyObject *bpy_package_py;
/* bpy_interface_atexit.c */

View File

@ -56,9 +56,6 @@ short BPy_reports_to_error(ReportList *reports, PyObject *exception, const bool
return (report_str == NULL) ? 0 : -1;
}
/**
* A version of #BKE_report_write_file_fp that uses Python's stdout.
*/
void BPy_reports_write_stdout(const ReportList *reports, const char *header)
{
if (header) {

View File

@ -33,6 +33,9 @@ struct ReportList;
/* error reporting */
short BPy_reports_to_error(struct ReportList *reports, PyObject *exception, const bool clear);
/**
* A version of #BKE_report_write_file_fp that uses Python's stdout.
*/
void BPy_reports_write_stdout(const struct ReportList *reports, const char *header);
bool BPy_errors_to_report_ex(struct ReportList *reports,
const char *error_prefix,

View File

@ -57,19 +57,12 @@
# include <opcode.h>
#endif
/**
* For PyDrivers
* (drivers using one-line Python expressions to express relationships between targets).
*/
PyObject *bpy_pydriver_Dict = NULL;
#ifdef USE_BYTECODE_WHITELIST
static PyObject *bpy_pydriver_Dict__whitelist = NULL;
#endif
/* For faster execution we keep a special dictionary for pydrivers, with
* the needed modules and aliases.
*/
int bpy_pydriver_create_dict(void)
{
PyObject *d, *mod;
@ -220,11 +213,6 @@ static void bpy_pydriver_namespace_clear_self(void)
}
}
/* Update function, it gets rid of pydrivers global dictionary, forcing
* BPY_driver_exec to recreate it. This function is used to force
* reloading the Blender text module "pydrivers.py", if available, so
* updates in it reach pydriver evaluation.
*/
void BPY_driver_reset(void)
{
PyGILState_STATE gilstate;
@ -429,28 +417,24 @@ static void bpy_pydriver_namespace_add_depsgraph(PyObject *driver_vars,
}
}
/**
* This evaluates Python driver expressions, `driver_orig->expression`
* is a Python expression that should evaluate to a float number, which is returned.
*
* (old) NOTE: PyGILState_Ensure() isn't always called because python can call
* the bake operator which intern starts a thread which calls scene update
* which does a driver update. to avoid a deadlock check #PyC_IsInterpreterActive()
* if #PyGILState_Ensure() is needed, see T27683.
*
* (new) NOTE: checking if python is running is not thread-safe T28114
* now release the GIL on python operator execution instead, using
* #PyEval_SaveThread() / #PyEval_RestoreThread() so we don't lock up blender.
*
* For copy-on-write we always cache expressions and write errors in the
* original driver, otherwise these would get freed while editing. Due to
* the GIL this is thread-safe.
*/
float BPY_driver_exec(struct PathResolvedRNA *anim_rna,
ChannelDriver *driver,
ChannelDriver *driver_orig,
const AnimationEvalContext *anim_eval_context)
{
/* (old) NOTE: PyGILState_Ensure() isn't always called because python can call
* the bake operator which intern starts a thread which calls scene update
* which does a driver update. to avoid a deadlock check #PyC_IsInterpreterActive()
* if #PyGILState_Ensure() is needed, see T27683.
*
* (new) NOTE: checking if python is running is not thread-safe T28114
* now release the GIL on python operator execution instead, using
* #PyEval_SaveThread() / #PyEval_RestoreThread() so we don't lock up blender.
*
* For copy-on-write we always cache expressions and write errors in the
* original driver, otherwise these would get freed while editing.
* Due to the GIL this is thread-safe. */
PyObject *driver_vars = NULL;
PyObject *retval = NULL;

View File

@ -24,7 +24,15 @@
extern "C" {
#endif
/**
* For faster execution we keep a special dictionary for py-drivers, with
* the needed modules and aliases.
*/
int bpy_pydriver_create_dict(void);
/**
* For PyDrivers
* (drivers using one-line Python expressions to express relationships between targets).
*/
extern PyObject *bpy_pydriver_Dict;
#ifdef __cplusplus

View File

@ -175,16 +175,6 @@ static void bpy_context_end(bContext *C)
CTX_wm_operator_poll_msg_clear(C);
}
/**
* Use for `CTX_*_set(..)` functions need to set values which are later read back as expected.
* In this case we don't want the Python context to override the values as it causes problems
* see T66256.
*
* \param dict_p: A pointer to #bContext.data.py_context so we can assign a new value.
* \param dict_orig: The value of #bContext.data.py_context_orig to check if we need to copy.
*
* \note Typically accessed via #BPY_context_dict_clear_members macro.
*/
void BPY_context_dict_clear_members_array(void **dict_p,
void *dict_orig,
const char *context_members[],

View File

@ -115,10 +115,6 @@ static void operator_properties_init(wmOperatorType *ot)
/* end 'ot->prop' assignment */
}
/**
* Generic function used by all Python defined operators
* it's passed as an argument to #WM_operatortype_append_ptr in for operator registration.
*/
void BPY_RNA_operator_wrapper(wmOperatorType *ot, void *userdata)
{
/* take care not to overwrite anything set in
@ -135,10 +131,6 @@ void BPY_RNA_operator_wrapper(wmOperatorType *ot, void *userdata)
operator_properties_init(ot);
}
/**
* Generic function used by all Python defined macro-operators
* it's passed as an argument to #WM_operatortype_append_ptr in for operator registration.
*/
void BPY_RNA_operator_macro_wrapper(wmOperatorType *ot, void *userdata)
{
wmOperatorType *data = (wmOperatorType *)userdata;

View File

@ -30,7 +30,15 @@ extern "C" {
PyObject *PYOP_wrap_macro_define(PyObject *self, PyObject *args);
/* exposed to rna/wm api */
/**
* Generic function used by all Python defined operators
* it's passed as an argument to #WM_operatortype_append_ptr in for operator registration.
*/
void BPY_RNA_operator_wrapper(struct wmOperatorType *ot, void *userdata);
/**
* Generic function used by all Python defined macro-operators
* it's passed as an argument to #WM_operatortype_append_ptr in for operator registration.
*/
void BPY_RNA_operator_macro_wrapper(struct wmOperatorType *ot, void *userdata);
#ifdef __cplusplus

View File

@ -4396,10 +4396,6 @@ PyObject *BPY_rna_props(void)
return submodule;
}
/**
* Run this on exit, clearing all Python callback users and disable the RNA callback,
* as it would be called after Python has already finished.
*/
void BPY_rna_props_clear_all(void)
{
/* Remove all user counts, so this isn't considered a leak from Python's perspective. */

View File

@ -25,6 +25,10 @@ extern "C" {
#endif
PyObject *BPY_rna_props(void);
/**
* Run this on exit, clearing all Python callback users and disable the RNA callback,
* as it would be called after Python has already finished.
*/
void BPY_rna_props_clear_all(void);
PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw);

View File

@ -1462,10 +1462,6 @@ PyObject *pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
return ret;
}
/**
* This function is used by operators and converting dicts into collections.
* It takes keyword args and fills them with property values.
*/
int pyrna_pydict_to_props(PointerRNA *ptr,
PyObject *kw,
const bool all_args,
@ -7545,7 +7541,6 @@ PyObject *pyrna_prop_CreatePyObject(PointerRNA *ptr, PropertyRNA *prop)
return (PyObject *)pyrna;
}
/* Utility func to be used by external modules, sneaky! */
PyObject *pyrna_id_CreatePyObject(ID *id)
{
if (id) {
@ -7777,9 +7772,6 @@ static struct PyModuleDef bpy_types_module_def = {
NULL, /* m_free */
};
/**
* Accessed from Python as 'bpy.types'
*/
PyObject *BPY_rna_types(void)
{
PyObject *submodule = PyModule_Create(&bpy_types_module_def);
@ -7864,11 +7856,6 @@ StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *e
}
/* Orphan functions, not sure where they should go. */
/**
* Get the SRNA for methods attached to types.
*
* Caller needs to raise error.
*/
StructRNA *srna_from_self(PyObject *self, const char *error_prefix)
{
@ -9094,9 +9081,6 @@ static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_cla
Py_RETURN_NONE;
}
/**
* Extend RNA types with C/API methods, properties.
*/
void pyrna_struct_type_extend_capi(struct StructRNA *srna,
struct PyMethodDef *method,
struct PyGetSetDef *getset)

View File

@ -990,9 +990,10 @@ PyObject *pyrna_py_from_array(PointerRNA *ptr, PropertyRNA *prop)
return pyrna_prop_CreatePyObject(ptr, prop);
}
/* TODO: multi-dimensional arrays. */
int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value)
{
/* TODO: multi-dimensional arrays. */
const int len = RNA_property_array_length(ptr, prop);
int type;
int i;

View File

@ -34,9 +34,6 @@
#include "bpy_rna_driver.h" /* own include */
/**
* A version of #driver_get_variable_value which returns a PyObject.
*/
PyObject *pyrna_driver_get_variable_value(struct ChannelDriver *driver, struct DriverTarget *dtar)
{
PyObject *driver_arg = NULL;

View File

@ -28,6 +28,9 @@ struct PathResolvedRNA;
extern "C" {
#endif
/**
* A version of #driver_get_variable_value which returns a #PyObject.
*/
PyObject *pyrna_driver_get_variable_value(struct ChannelDriver *driver, struct DriverTarget *dtar);
PyObject *pyrna_driver_self_from_anim_rna(struct PathResolvedRNA *anim_rna);

View File

@ -77,11 +77,6 @@ static int mathutils_array_parse_fast(float *array,
return size;
}
/**
* helper function that returns a Python `__hash__`.
*
* \note consistent with the equivalent tuple of floats (CPython's 'tuplehash')
*/
Py_hash_t mathutils_array_hash(const float *array, size_t array_len)
{
int i;
@ -114,7 +109,6 @@ Py_hash_t mathutils_array_hash(const float *array, size_t array_len)
return x;
}
/* helper function returns length of the 'value', -1 on error */
int mathutils_array_parse(
float *array, int array_min, int array_max, PyObject *value, const char *error_prefix)
{
@ -211,7 +205,6 @@ int mathutils_array_parse(
return size;
}
/* on error, -1 is returned and no allocation is made */
int mathutils_array_parse_alloc(float **array,
int array_min,
PyObject *value,
@ -279,7 +272,6 @@ int mathutils_array_parse_alloc(float **array,
return ret;
}
/* parse an array of vectors */
int mathutils_array_parse_alloc_v(float **array,
int array_dim,
PyObject *value,
@ -321,7 +313,6 @@ int mathutils_array_parse_alloc_v(float **array,
return size;
}
/* Parse an sequence array_dim integers into array. */
int mathutils_int_array_parse(int *array, int array_dim, PyObject *value, const char *error_prefix)
{
int size, i;
@ -357,7 +348,6 @@ int mathutils_int_array_parse(int *array, int array_dim, PyObject *value, const
return size;
}
/* Parse sequence of array_dim sequences of integers and return allocated result. */
int mathutils_array_parse_alloc_vi(int **array,
int array_dim,
PyObject *value,
@ -395,12 +385,6 @@ int mathutils_array_parse_alloc_vi(int **array,
return size;
}
/* Parse sequence of variable-length sequences of int and return allocated
* triple of arrays to represent the result:
* The flattened sequences are put into *array.
* The start index of each sequence goes into start_table.
* The length of each index goes into len_table.
*/
int mathutils_array_parse_alloc_viseq(
int **array, int **start_table, int **len_table, PyObject *value, const char *error_prefix)
{
@ -560,7 +544,6 @@ int EXPP_VectorsAreEqual(const float *vecA, const float *vecB, int size, int flo
}
#ifndef MATH_STANDALONE
/* dynstr as python string utility functions, frees 'ds'! */
PyObject *mathutils_dynstr_to_py(struct DynStr *ds)
{
const int ds_len = BLI_dynstr_get_len(ds); /* space for \0 */

View File

@ -162,28 +162,56 @@ void _BaseMathObject_RaiseNotFrozenExc(const BaseMathObject *self);
0)
/* utility func */
/**
* Helper function.
* \return length of `value`, -1 on error.
*/
int mathutils_array_parse(
float *array, int array_min, int array_max, PyObject *value, const char *error_prefix);
/**
* \return -1 is returned on error and no allocation is made.
*/
int mathutils_array_parse_alloc(float **array,
int array_min,
PyObject *value,
const char *error_prefix);
/**
* Parse an array of vectors.
*/
int mathutils_array_parse_alloc_v(float **array,
int array_dim,
PyObject *value,
const char *error_prefix);
/**
* Parse an sequence array_dim integers into array.
*/
int mathutils_int_array_parse(int *array,
int array_dim,
PyObject *value,
const char *error_prefix);
/**
* Parse sequence of array_dim sequences of integers and return allocated result.
*/
int mathutils_array_parse_alloc_vi(int **array,
int array_dim,
PyObject *value,
const char *error_prefix);
/**
* Parse sequence of variable-length sequences of int and return allocated
* triple of arrays to represent the result:
* The flattened sequences are put into *array.
* The start index of each sequence goes into start_table.
* The length of each index goes into len_table.
*/
int mathutils_array_parse_alloc_viseq(
int **array, int **start_table, int **len_table, PyObject *value, const char *error_prefix);
int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix);
/**
* helper function that returns a Python `__hash__`.
*
* \note consistent with the equivalent tuple of floats (CPython's 'tuplehash')
*/
Py_hash_t mathutils_array_hash(const float *float_array, size_t array_len);
/* zero remaining unused elements of the array */
@ -194,9 +222,21 @@ Py_hash_t mathutils_array_hash(const float *float_array, size_t array_len);
#define MU_ARRAY_FLAGS (MU_ARRAY_ZERO | MU_ARRAY_SPILL)
/**
* Column vector multiplication (Matrix * Vector).
* <pre>
* [1][4][7] [a]
* [2][5][8] * [b]
* [3][6][9] [c]
* </pre>
*
* \note Vector/Matrix multiplication is not commutative.
* \note Assume read callbacks have been done first.
*/
int column_vector_multiplication(float r_vec[4], VectorObject *vec, MatrixObject *mat);
#ifndef MATH_STANDALONE
/* dynstr as python string utility functions */
/* dynstr as python string utility functions, frees 'ds'! */
PyObject *mathutils_dynstr_to_py(struct DynStr *ds);
#endif

View File

@ -3382,9 +3382,6 @@ PyObject *Matrix_CreatePyObject_cb(
return (PyObject *)self;
}
/**
* \param mat: Initialized matrix value to use in-place, allocated with #PyMem_Malloc
*/
PyObject *Matrix_CreatePyObject_alloc(float *mat,
const ushort num_col,
const ushort num_row,

View File

@ -75,6 +75,9 @@ PyObject *Matrix_CreatePyObject_cb(PyObject *user,
unsigned char cb_type,
unsigned char cb_subtype) ATTR_WARN_UNUSED_RESULT;
/**
* \param mat: Initialized matrix value to use in-place, allocated with #PyMem_Malloc
*/
PyObject *Matrix_CreatePyObject_alloc(float *mat,
const ushort num_col,
const ushort num_row,

View File

@ -1676,17 +1676,6 @@ static PyObject *Vector_isub(PyObject *v1, PyObject *v2)
/*------------------------obj * obj------------------------------
* multiplication */
/**
* Column vector multiplication (Matrix * Vector).
* <pre>
* [1][4][7] [a]
* [2][5][8] * [b]
* [3][6][9] [c]
* </pre>
*
* \note Vector/Matrix multiplication is not commutative.
* \note Assume read callbacks have been done first.
*/
int column_vector_multiplication(float r_vec[MAX_DIMENSIONS], VectorObject *vec, MatrixObject *mat)
{
float vec_cpy[MAX_DIMENSIONS];
@ -3166,11 +3155,6 @@ PyObject *Vector_CreatePyObject(const float *vec, const int size, PyTypeObject *
return (PyObject *)self;
}
/**
* Create a vector that wraps existing memory.
*
* \param vec: Use this vector in-place.
*/
PyObject *Vector_CreatePyObject_wrap(float *vec, const int size, PyTypeObject *base_type)
{
VectorObject *self;
@ -3194,10 +3178,6 @@ PyObject *Vector_CreatePyObject_wrap(float *vec, const int size, PyTypeObject *b
return (PyObject *)self;
}
/**
* Create a vector where the value is defined by registered callbacks,
* see: #Mathutils_RegisterCallback
*/
PyObject *Vector_CreatePyObject_cb(PyObject *cb_user, int size, uchar cb_type, uchar cb_subtype)
{
VectorObject *self = (VectorObject *)Vector_CreatePyObject(NULL, size, NULL);
@ -3212,9 +3192,6 @@ PyObject *Vector_CreatePyObject_cb(PyObject *cb_user, int size, uchar cb_type, u
return (PyObject *)self;
}
/**
* \param vec: Initialized vector value to use in-place, allocated with #PyMem_Malloc
*/
PyObject *Vector_CreatePyObject_alloc(float *vec, const int size, PyTypeObject *base_type)
{
VectorObject *self;

View File

@ -35,14 +35,26 @@ typedef struct {
PyObject *Vector_CreatePyObject(const float *vec,
const int size,
PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT;
/**
* Create a vector that wraps existing memory.
*
* \param vec: Use this vector in-place.
*/
PyObject *Vector_CreatePyObject_wrap(float *vec,
const int size,
PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL(1);
/**
* Create a vector where the value is defined by registered callbacks,
* see: #Mathutils_RegisterCallback
*/
PyObject *Vector_CreatePyObject_cb(PyObject *user,
int size,
unsigned char cb_type,
unsigned char subtype) ATTR_WARN_UNUSED_RESULT;
/**
* \param vec: Initialized vector value to use in-place, allocated with #PyMem_Malloc
*/
PyObject *Vector_CreatePyObject_alloc(float *vec,
const int size,
PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT