Blender V4.3
bpy_rna_data.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
16#include <Python.h>
17#include <cstddef>
18
21
22#include "BLI_string.h"
23#include "BLI_utildefines.h"
24
25#include "BKE_global.hh"
26#include "BKE_main.hh"
27
28#include "RNA_access.hh"
29#include "RNA_prototypes.hh"
30
31#include "bpy_rna.hh"
32#include "bpy_rna_data.hh"
33
35 PyObject_HEAD /* Required Python macro. */
37 char filepath[1024];
38};
39
40static PyObject *bpy_rna_data_temp_data(PyObject *self, PyObject *args, PyObject *kw);
42static PyObject *bpy_rna_data_context_exit(BPy_DataContext *self, PyObject *args);
43
44#if (defined(__GNUC__) && !defined(__clang__))
45# pragma GCC diagnostic push
46# pragma GCC diagnostic ignored "-Wcast-function-type"
47#endif
48
49static PyMethodDef bpy_rna_data_context_methods[] = {
50 {"__enter__", (PyCFunction)bpy_rna_data_context_enter, METH_NOARGS},
51 {"__exit__", (PyCFunction)bpy_rna_data_context_exit, METH_VARARGS},
52 {nullptr} /* sentinel */
53};
54
55#if (defined(__GNUC__) && !defined(__clang__))
56# pragma GCC diagnostic pop
57#endif
58
59static int bpy_rna_data_context_traverse(BPy_DataContext *self, visitproc visit, void *arg)
60{
61 Py_VISIT(self->data_rna);
62 return 0;
63}
64
66{
67 Py_CLEAR(self->data_rna);
68 return 0;
69}
70
72{
73 PyObject_GC_UnTrack(self);
74 Py_CLEAR(self->data_rna);
75 PyObject_GC_Del(self);
76}
77static PyTypeObject bpy_rna_data_context_Type = {
78 /*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
79 /*tp_name*/ "bpy_rna_data_context",
80 /*tp_basicsize*/ sizeof(BPy_DataContext),
81 /*tp_itemsize*/ 0,
82 /*tp_dealloc*/ (destructor)bpy_rna_data_context_dealloc,
83 /*tp_vectorcall_offset*/ 0,
84 /*tp_getattr*/ nullptr,
85 /*tp_setattr*/ nullptr,
86 /*tp_as_async*/ nullptr,
87 /*tp_repr*/ nullptr,
88 /*tp_as_number*/ nullptr,
89 /*tp_as_sequence*/ nullptr,
90 /*tp_as_mapping*/ nullptr,
91 /*tp_hash*/ nullptr,
92 /*tp_call*/ nullptr,
93 /*tp_str*/ nullptr,
94 /*tp_getattro*/ nullptr,
95 /*tp_setattro*/ nullptr,
96 /*tp_as_buffer*/ nullptr,
97 /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
98 /*tp_doc*/ nullptr,
99 /*tp_traverse*/ (traverseproc)bpy_rna_data_context_traverse,
100 /*tp_clear*/ (inquiry)bpy_rna_data_context_clear,
101 /*tp_richcompare*/ nullptr,
102 /*tp_weaklistoffset*/ 0,
103 /*tp_iter*/ nullptr,
104 /*tp_iternext*/ nullptr,
105 /*tp_methods*/ bpy_rna_data_context_methods,
106 /*tp_members*/ nullptr,
107 /*tp_getset*/ nullptr,
108 /*tp_base*/ nullptr,
109 /*tp_dict*/ nullptr,
110 /*tp_descr_get*/ nullptr,
111 /*tp_descr_set*/ nullptr,
112 /*tp_dictoffset*/ 0,
113 /*tp_init*/ nullptr,
114 /*tp_alloc*/ nullptr,
115 /*tp_new*/ nullptr,
116 /*tp_free*/ nullptr,
117 /*tp_is_gc*/ nullptr,
118 /*tp_bases*/ nullptr,
119 /*tp_mro*/ nullptr,
120 /*tp_cache*/ nullptr,
121 /*tp_subclasses*/ nullptr,
122 /*tp_weaklist*/ nullptr,
123 /*tp_del*/ nullptr,
124 /*tp_version_tag*/ 0,
125 /*tp_finalize*/ nullptr,
126 /*tp_vectorcall*/ nullptr,
127};
128
130 /* Wrap. */
131 bpy_rna_data_context_load_doc,
132 ".. method:: temp_data(filepath=None)\n"
133 "\n"
134 " A context manager that temporarily creates blender file data.\n"
135 "\n"
136 " :arg filepath: The file path for the newly temporary data. "
137 "When None, the path of the currently open file is used.\n"
138 " :type filepath: str | bytes | None\n"
139 "\n"
140 " :return: Blend file data which is freed once the context exists.\n"
141 " :rtype: :class:`bpy.types.BlendData`\n");
142
143static PyObject *bpy_rna_data_temp_data(PyObject * /*self*/, PyObject *args, PyObject *kw)
144{
145 PyC_UnicodeAsBytesAndSize_Data filepath_data = {nullptr};
147 static const char *_keywords[] = {"filepath", nullptr};
148 static _PyArg_Parser _parser = {
150 "|$" /* Optional keyword only arguments. */
151 "O&" /* `filepath` */
152 ":temp_data",
153 _keywords,
154 nullptr,
155 };
156 if (!_PyArg_ParseTupleAndKeywordsFast(
157 args, kw, &_parser, PyC_ParseUnicodeAsBytesAndSize_OrNone, &filepath_data))
158 {
159 return nullptr;
160 }
161
162 ret = PyObject_GC_New(BPy_DataContext, &bpy_rna_data_context_Type);
163
164 STRNCPY(ret->filepath, filepath_data.value ? filepath_data.value : G_MAIN->filepath);
165 Py_XDECREF(filepath_data.value_coerce);
166
167 return (PyObject *)ret;
168}
169
171{
172 Main *bmain_temp = BKE_main_new();
173 PointerRNA ptr = RNA_pointer_create(nullptr, &RNA_BlendData, bmain_temp);
174
176
177 BLI_assert(!PyObject_GC_IsTracked((PyObject *)self));
178 PyObject_GC_Track(self);
179
180 return (PyObject *)self->data_rna;
181}
182
183static PyObject *bpy_rna_data_context_exit(BPy_DataContext *self, PyObject * /*args*/)
184{
185 BKE_main_free(static_cast<Main *>(self->data_rna->ptr.data));
186 RNA_POINTER_INVALIDATE(&self->data_rna->ptr);
187 Py_RETURN_NONE;
188}
189
190#if (defined(__GNUC__) && !defined(__clang__))
191# pragma GCC diagnostic push
192# pragma GCC diagnostic ignored "-Wcast-function-type"
193#endif
194
196 "temp_data",
197 (PyCFunction)bpy_rna_data_temp_data,
198 METH_STATIC | METH_VARARGS | METH_KEYWORDS,
199 bpy_rna_data_context_load_doc,
200};
201
202#if (defined(__GNUC__) && !defined(__clang__))
203# pragma GCC diagnostic pop
204#endif
205
207{
208 if (PyType_Ready(&bpy_rna_data_context_Type) < 0) {
209 return -1;
210 }
211
212 return 0;
213}
#define G_MAIN
Main * BKE_main_new(void)
Definition main.cc:45
void BKE_main_free(Main *bmain)
Definition main.cc:175
#define BLI_assert(a)
Definition BLI_assert.h:50
#define STRNCPY(dst, src)
Definition BLI_string.h:593
#define RNA_POINTER_INVALIDATE(ptr)
PyObject * self
PyObject * pyrna_struct_CreatePyObject(PointerRNA *ptr)
Definition bpy_rna.cc:7694
int BPY_rna_data_context_type_ready()
static PyObject * bpy_rna_data_context_enter(BPy_DataContext *self)
static int bpy_rna_data_context_clear(BPy_DataContext *self)
static PyTypeObject bpy_rna_data_context_Type
PyDoc_STRVAR(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_context_exit(BPy_DataContext *self, PyObject *args)
static int bpy_rna_data_context_traverse(BPy_DataContext *self, visitproc visit, void *arg)
PyMethodDef BPY_rna_data_context_method_def
static PyObject * bpy_rna_data_temp_data(PyObject *self, PyObject *args, PyObject *kw)
static void bpy_rna_data_context_dealloc(BPy_DataContext *self)
static PyMethodDef bpy_rna_data_context_methods[]
int PyC_ParseUnicodeAsBytesAndSize_OrNone(PyObject *o, void *p)
header-only compatibility defines.
#define PY_ARG_PARSER_HEAD_COMPAT()
return ret
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
char filepath[1024]
PyObject_HEAD BPy_StructRNA * data_rna
PointerRNA * ptr
Definition wm_files.cc:4126