FreeCAD

Форк
0
/
FeaturePythonPyImp.inl 
204 строки · 8.8 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2013 Werner Mayer <wmayer[at]users.sourceforge.net>     *
3
 *                                                                         *
4
 *   This file is part of the FreeCAD CAx development system.              *
5
 *                                                                         *
6
 *   This library is free software; you can redistribute it and/or         *
7
 *   modify it under the terms of the GNU Library General Public           *
8
 *   License as published by the Free Software Foundation; either          *
9
 *   version 2 of the License, or (at your option) any later version.      *
10
 *                                                                         *
11
 *   This library  is distributed in the hope that it will be useful,      *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14
 *   GNU Library General Public License for more details.                  *
15
 *                                                                         *
16
 *   You should have received a copy of the GNU Library General Public     *
17
 *   License along with this library; see the file COPYING.LIB. If not,    *
18
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
19
 *   Suite 330, Boston, MA  02111-1307, USA                                *
20
 *                                                                         *
21
 ***************************************************************************/
22

23

24
// clang-format off
25
namespace App
26
{
27

28
/// Type structure of FeaturePythonPyT
29
template<class FeaturePyT>
30
PyTypeObject FeaturePythonPyT<FeaturePyT>::Type = {
31
    PyVarObject_HEAD_INIT(&PyType_Type,0)
32
    "FeaturePython",                                  /*tp_name*/
33
    sizeof(FeaturePythonPyT),                         /*tp_basicsize*/
34
    0,                                                /*tp_itemsize*/
35
    /* methods */
36
    FeaturePyT::PyDestructor,                         /*tp_dealloc*/
37
#if PY_VERSION_HEX >= 0x03080000
38
    0,                                                /*tp_vectorcall_offset*/
39
#else
40
    nullptr,                                          /*tp_print*/
41
#endif
42
    nullptr,                                          /*tp_getattr*/
43
    nullptr,                                          /*tp_setattr*/
44
    nullptr,                                          /*tp_compare*/
45
    nullptr,                                          /*tp_repr*/
46
    nullptr,                                          /*tp_as_number*/
47
    nullptr,                                          /*tp_as_sequence*/
48
    nullptr,                                          /*tp_as_mapping*/
49
    nullptr,                                          /*tp_hash*/
50
    nullptr,                                          /*tp_call */
51
    nullptr,                                          /*tp_str  */
52
    FeaturePyT::__getattro,                           /*tp_getattro*/
53
    __setattro,                                       /*tp_setattro*/
54
    /* --- Functions to access object as input/output buffer ---------*/
55
    nullptr,                                          /* tp_as_buffer */
56
    /* --- Flags to define presence of optional/expanded features */
57
    Py_TPFLAGS_BASETYPE|Py_TPFLAGS_DEFAULT,           /*tp_flags */
58
    "This is the father of all Feature classes",      /*tp_doc */
59
    nullptr,                                          /*tp_traverse */
60
    nullptr,                                          /*tp_clear */
61
    nullptr,                                          /*tp_richcompare */
62
    0,                                                /*tp_weaklistoffset */
63
    nullptr,                                          /*tp_iter */
64
    nullptr,                                          /*tp_iternext */
65
    nullptr,                                          /*tp_methods */
66
    nullptr,                                          /*tp_members */
67
    nullptr,                                          /*tp_getset */
68
    &FeaturePyT::Type,                                /*tp_base */
69
    nullptr,                                          /*tp_dict */
70
    nullptr,                                          /*tp_descr_get */
71
    nullptr,                                          /*tp_descr_set */
72
    0,                                                /*tp_dictoffset */
73
    FeaturePyT::__PyInit,                             /*tp_init */
74
    nullptr,                                          /*tp_alloc */
75
    nullptr,                                          /*tp_new */
76
    nullptr,                                          /*tp_free   Low-level free-memory routine */
77
    nullptr,                                          /*tp_is_gc  For PyObject_IS_GC */
78
    nullptr,                                          /*tp_bases */
79
    nullptr,                                          /*tp_mro    method resolution order */
80
    nullptr,                                          /*tp_cache */
81
    nullptr,                                          /*tp_subclasses */
82
    nullptr,                                          /*tp_weaklist */
83
    nullptr,                                          /*tp_del */
84
    0,                                                /*tp_version_tag */
85
    nullptr                                           /*tp_finalize */
86
#if PY_VERSION_HEX >= 0x03080000
87
    ,0                                                /*tp_vectorcall */
88
#if PY_VERSION_HEX >= 0x030c0000
89
    ,0                                                /*tp_watched */
90
#endif
91
#endif
92
};
93

94
template<class FeaturePyT>
95
FeaturePythonPyT<FeaturePyT>::FeaturePythonPyT(Base::BaseClass *pcObject, PyTypeObject *T)
96
    : FeaturePyT(static_cast<typename FeaturePyT::PointerType>(pcObject), T)
97
{
98
    Base::PyGILStateLocker lock;
99
    dict_methods = PyDict_New();
100
}
101

102
template<class FeaturePyT>
103
FeaturePythonPyT<FeaturePyT>::~FeaturePythonPyT()
104
{
105
    Base::PyGILStateLocker lock;
106
    Py_DECREF(dict_methods);
107
}
108

109
template<class FeaturePyT>
110
int FeaturePythonPyT<FeaturePyT>::__setattro(PyObject *obj, PyObject *attro, PyObject *value)
111
{
112
    const char *attr;
113
    attr = PyUnicode_AsUTF8(attro);
114
    // This overwrites PyObjectBase::__setattr because this actively disallows to delete an attribute
115
    //
116

117
    if (!static_cast<Base::PyObjectBase*>(obj)->isValid()){
118
        PyErr_Format(PyExc_ReferenceError, "Cannot access attribute '%s' of deleted object", attr);
119
        return -1;
120
    }
121

122
    int ret = static_cast<Base::PyObjectBase*>(obj)->_setattr(attr, value);
123
    if (ret == 0) {
124
        static_cast<Base::PyObjectBase*>(obj)->startNotify();
125
    }
126
    return ret;
127
}
128

129

130
template<class FeaturePyT>
131
int FeaturePythonPyT<FeaturePyT>::_setattr(const char *attr, PyObject *value)
132
{
133
    App::Property *prop = FeaturePyT::getPropertyContainerPtr()->getPropertyByName(attr);
134
    if (prop && !value) {
135
        PyErr_Format(PyExc_AttributeError, "Cannot delete attribute: '%s'", attr);
136
        return -1;
137
    }
138

139
    int returnValue = FeaturePyT::_setattr(attr, value);
140
    if (returnValue == -1) {
141
        PyObject* dict_item = value;
142
        if (value) {
143
            if (PyFunction_Check(value)) {
144
                PyErr_Clear();
145
                dict_item = PyMethod_New(value, this);
146
                returnValue = PyDict_SetItemString(dict_methods, attr, dict_item);
147
                Py_XDECREF(dict_item);
148
            }
149
        }
150
        else {
151
            // delete
152
            PyErr_Clear();
153
            returnValue = PyDict_DelItemString(dict_methods, attr);
154
            if (returnValue < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
155
                PyErr_SetString(PyExc_AttributeError, attr);
156
        }
157
    }
158
    return returnValue;
159
}
160

161
template<class FeaturePyT>
162
PyObject *FeaturePythonPyT<FeaturePyT>::_getattr(const char *attr)
163
{
164
    // See CallTipsList::extractTips
165
    if (Base::streq(attr, "__fc_template__")) {
166
        Py_INCREF(Py_None);
167
        return Py_None;
168
    }
169

170
    // get only attributes of this type
171
    if (Base::streq(attr, "__dict__")) {
172
        // Return the default dict
173
        PyTypeObject *tp = this->ob_type;
174
        // register type if needed
175
        if (!tp->tp_dict) {
176
            if (PyType_Ready(tp) < 0)
177
                return nullptr;
178
        }
179

180
        PyObject* dict = FeaturePyT::_getattr(attr);
181
        if (dict && PyDict_CheckExact(dict)) {
182
            PyObject* dict_old = dict;
183
            dict = PyDict_Copy(dict_old);
184
            Py_DECREF(dict_old); // delete old dict
185
            PyDict_Merge(dict, dict_methods, 0);
186
        }
187
        return dict;
188
    }
189

190
    // find the attribute in the dict
191
    PyObject *dict_item = nullptr;
192
    dict_item = PyDict_GetItemString(dict_methods, attr);
193
    if (dict_item) {
194
        Py_INCREF(dict_item);
195
        return dict_item;
196
    }
197

198
    // search for the attribute in the base class
199
    PyErr_Clear();
200
    return FeaturePyT::_getattr(attr);
201
}
202

203
} //namespace App
204
// clang-format on
205

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.