Files
test2/source/blender/python/intern/bpy_rna_data.cc
Campbell Barton 3bcfb151c1 PyDoc: use Python's type annotation syntax for doc-strings
Replace plain-text type information with the type syntax used
for Python's type annotations as it's more concise, especially for
callbacks which often didn't include useful type information.

Note that this change only applies to inline doc-strings,
generated doc-strings from RNA need to be updated separately.

Details:

- Many minor corrections were made when "list" was incorrectly used
  instead of "sequence".
- Some type information wasn't defined in the doc-strings and has been
  added.
- Verbose type info would benefit from support for type aliases.
2024-11-03 15:44:35 +11:00

214 lines
6.0 KiB
C++

/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup pythonintern
*
* This file defines the API to support temporarily creating #Main data.
* The only use case for this is currently to support temporarily loading data-blocks
* which can be freed, without them polluting the current #G_MAIN.
*
* This is exposed via a context manager `bpy.types.BlendData.temp_data(...)`
* which returns a new `bpy.types.BlendData` that is freed once the context manager exits.
*/
#include <Python.h>
#include <cstddef>
#include "../generic/py_capi_utils.hh"
#include "../generic/python_compat.hh"
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BKE_global.hh"
#include "BKE_main.hh"
#include "RNA_access.hh"
#include "RNA_prototypes.hh"
#include "bpy_rna.hh"
#include "bpy_rna_data.hh"
struct BPy_DataContext {
PyObject_HEAD /* Required Python macro. */
BPy_StructRNA *data_rna;
char filepath[1024];
};
static PyObject *bpy_rna_data_temp_data(PyObject *self, PyObject *args, PyObject *kw);
static PyObject *bpy_rna_data_context_enter(BPy_DataContext *self);
static PyObject *bpy_rna_data_context_exit(BPy_DataContext *self, PyObject *args);
#if (defined(__GNUC__) && !defined(__clang__))
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wcast-function-type"
#endif
static PyMethodDef bpy_rna_data_context_methods[] = {
{"__enter__", (PyCFunction)bpy_rna_data_context_enter, METH_NOARGS},
{"__exit__", (PyCFunction)bpy_rna_data_context_exit, METH_VARARGS},
{nullptr} /* sentinel */
};
#if (defined(__GNUC__) && !defined(__clang__))
# pragma GCC diagnostic pop
#endif
static int bpy_rna_data_context_traverse(BPy_DataContext *self, visitproc visit, void *arg)
{
Py_VISIT(self->data_rna);
return 0;
}
static int bpy_rna_data_context_clear(BPy_DataContext *self)
{
Py_CLEAR(self->data_rna);
return 0;
}
static void bpy_rna_data_context_dealloc(BPy_DataContext *self)
{
PyObject_GC_UnTrack(self);
Py_CLEAR(self->data_rna);
PyObject_GC_Del(self);
}
static PyTypeObject bpy_rna_data_context_Type = {
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
/*tp_name*/ "bpy_rna_data_context",
/*tp_basicsize*/ sizeof(BPy_DataContext),
/*tp_itemsize*/ 0,
/*tp_dealloc*/ (destructor)bpy_rna_data_context_dealloc,
/*tp_vectorcall_offset*/ 0,
/*tp_getattr*/ nullptr,
/*tp_setattr*/ nullptr,
/*tp_as_async*/ nullptr,
/*tp_repr*/ nullptr,
/*tp_as_number*/ nullptr,
/*tp_as_sequence*/ nullptr,
/*tp_as_mapping*/ nullptr,
/*tp_hash*/ nullptr,
/*tp_call*/ nullptr,
/*tp_str*/ nullptr,
/*tp_getattro*/ nullptr,
/*tp_setattro*/ nullptr,
/*tp_as_buffer*/ nullptr,
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
/*tp_doc*/ nullptr,
/*tp_traverse*/ (traverseproc)bpy_rna_data_context_traverse,
/*tp_clear*/ (inquiry)bpy_rna_data_context_clear,
/*tp_richcompare*/ nullptr,
/*tp_weaklistoffset*/ 0,
/*tp_iter*/ nullptr,
/*tp_iternext*/ nullptr,
/*tp_methods*/ bpy_rna_data_context_methods,
/*tp_members*/ nullptr,
/*tp_getset*/ nullptr,
/*tp_base*/ nullptr,
/*tp_dict*/ nullptr,
/*tp_descr_get*/ nullptr,
/*tp_descr_set*/ nullptr,
/*tp_dictoffset*/ 0,
/*tp_init*/ nullptr,
/*tp_alloc*/ nullptr,
/*tp_new*/ nullptr,
/*tp_free*/ nullptr,
/*tp_is_gc*/ nullptr,
/*tp_bases*/ nullptr,
/*tp_mro*/ nullptr,
/*tp_cache*/ nullptr,
/*tp_subclasses*/ nullptr,
/*tp_weaklist*/ nullptr,
/*tp_del*/ nullptr,
/*tp_version_tag*/ 0,
/*tp_finalize*/ nullptr,
/*tp_vectorcall*/ nullptr,
};
PyDoc_STRVAR(
/* Wrap. */
bpy_rna_data_context_load_doc,
".. method:: temp_data(filepath=None)\n"
"\n"
" A context manager that temporarily creates blender file data.\n"
"\n"
" :arg filepath: The file path for the newly temporary data. "
"When None, the path of the currently open file is used.\n"
" :type filepath: str | bytes | None\n"
"\n"
" :return: Blend file data which is freed once the context exists.\n"
" :rtype: :class:`bpy.types.BlendData`\n");
static PyObject *bpy_rna_data_temp_data(PyObject * /*self*/, PyObject *args, PyObject *kw)
{
PyC_UnicodeAsBytesAndSize_Data filepath_data = {nullptr};
BPy_DataContext *ret;
static const char *_keywords[] = {"filepath", nullptr};
static _PyArg_Parser _parser = {
PY_ARG_PARSER_HEAD_COMPAT()
"|$" /* Optional keyword only arguments. */
"O&" /* `filepath` */
":temp_data",
_keywords,
nullptr,
};
if (!_PyArg_ParseTupleAndKeywordsFast(
args, kw, &_parser, PyC_ParseUnicodeAsBytesAndSize_OrNone, &filepath_data))
{
return nullptr;
}
ret = PyObject_GC_New(BPy_DataContext, &bpy_rna_data_context_Type);
STRNCPY(ret->filepath, filepath_data.value ? filepath_data.value : G_MAIN->filepath);
Py_XDECREF(filepath_data.value_coerce);
return (PyObject *)ret;
}
static PyObject *bpy_rna_data_context_enter(BPy_DataContext *self)
{
Main *bmain_temp = BKE_main_new();
PointerRNA ptr = RNA_pointer_create(nullptr, &RNA_BlendData, bmain_temp);
self->data_rna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr);
BLI_assert(!PyObject_GC_IsTracked((PyObject *)self));
PyObject_GC_Track(self);
return (PyObject *)self->data_rna;
}
static PyObject *bpy_rna_data_context_exit(BPy_DataContext *self, PyObject * /*args*/)
{
BKE_main_free(static_cast<Main *>(self->data_rna->ptr.data));
RNA_POINTER_INVALIDATE(&self->data_rna->ptr);
Py_RETURN_NONE;
}
#if (defined(__GNUC__) && !defined(__clang__))
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wcast-function-type"
#endif
PyMethodDef BPY_rna_data_context_method_def = {
"temp_data",
(PyCFunction)bpy_rna_data_temp_data,
METH_STATIC | METH_VARARGS | METH_KEYWORDS,
bpy_rna_data_context_load_doc,
};
#if (defined(__GNUC__) && !defined(__clang__))
# pragma GCC diagnostic pop
#endif
int BPY_rna_data_context_type_ready()
{
if (PyType_Ready(&bpy_rna_data_context_Type) < 0) {
return -1;
}
return 0;
}