1
/***************************************************************************
2
* Copyright (c) 2019 Werner Mayer <wmayer[at]users.sourceforge.net> *
4
* This file is part of the FreeCAD CAx development system. *
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. *
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. *
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., 51 Franklin Street, *
19
* Fifth Floor, Boston, MA 02110-1301, USA *
21
***************************************************************************/
24
#include "PreCompiled.h"
27
#include "BaseClassPy.h"
28
#include "BindingManager.h"
34
// returns a string which represent the object e.g. when printed in python
35
std::string TypePy::representation() const
37
std::stringstream str;
38
str << "<class '" << getBaseTypePtr()->getName() << "'>";
42
PyObject* TypePy::fromName(PyObject* args)
45
if (!PyArg_ParseTuple(args, "s", &name)) {
49
Base::Type type = Base::Type::fromName(name);
50
return new TypePy(new Base::Type(type));
53
PyObject* TypePy::fromKey(PyObject* args)
55
unsigned int index {};
56
if (!PyArg_ParseTuple(args, "I", &index)) {
60
Base::Type type = Base::Type::fromKey(index);
61
return new TypePy(new Base::Type(type));
64
PyObject* TypePy::getNumTypes(PyObject* args)
66
if (!PyArg_ParseTuple(args, "")) {
70
int num = Base::Type::getNumTypes();
71
return PyLong_FromLong(num);
74
PyObject* TypePy::getBadType(PyObject* args)
76
if (!PyArg_ParseTuple(args, "")) {
80
Base::Type type = Base::Type::badType();
81
return new TypePy(new Base::Type(type));
84
PyObject* TypePy::getParent(PyObject* args)
86
if (!PyArg_ParseTuple(args, "")) {
90
Base::Type type = getBaseTypePtr()->getParent();
91
return new TypePy(new Base::Type(type));
94
PyObject* TypePy::isBad(PyObject* args)
96
if (!PyArg_ParseTuple(args, "")) {
100
bool val = getBaseTypePtr()->isBad();
101
return PyBool_FromLong(val ? 1 : 0);
104
PyObject* TypePy::isDerivedFrom(PyObject* args)
110
if (PyArg_ParseTuple(args, "s", &name)) {
111
type = Base::Type::fromName(name);
117
if (PyArg_ParseTuple(args, "O!", &TypePy::Type, &py)) {
118
type = *static_cast<TypePy*>(py)->getBaseTypePtr();
122
PyErr_SetString(PyExc_TypeError, "TypeId or str expected");
126
bool val = (type != Base::Type::badType() && getBaseTypePtr()->isDerivedFrom(type));
127
return PyBool_FromLong(val ? 1 : 0);
130
PyObject* TypePy::getAllDerivedFrom(PyObject* args)
136
if (PyArg_ParseTuple(args, "s", &name)) {
137
type = Base::Type::fromName(name);
143
if (PyArg_ParseTuple(args, "O!", &TypePy::Type, &py)) {
144
type = *static_cast<TypePy*>(py)->getBaseTypePtr();
148
PyErr_SetString(PyExc_TypeError, "TypeId or str expected");
152
std::vector<Base::Type> ary;
153
Base::Type::getAllDerivedFrom(type, ary);
155
for (const auto& it : ary) {
156
res.append(Py::asObject(new TypePy(new Base::Type(it))));
158
return Py::new_reference_to(res);
161
PyObject* TypePy::getAllDerived(PyObject* args)
163
if (!PyArg_ParseTuple(args, "")) {
167
Base::Type type = Base::Type::fromName(getBaseTypePtr()->getName());
168
std::vector<Base::Type> ary;
169
Base::Type::getAllDerivedFrom(type, ary);
171
for (const auto& it : ary) {
172
res.append(Py::asObject(new TypePy(new Base::Type(it))));
174
return Py::new_reference_to(res);
179
void deallocPyObject(PyObject* py)
181
Base::PyObjectBase* pybase = static_cast<Base::PyObjectBase*>(py);
182
Base::BaseClass* base = static_cast<Base::BaseClass*>(pybase->getTwinPointer());
183
if (Base::BindingManager::instance().retrieveWrapper(base) == py) {
184
Base::BindingManager::instance().releaseWrapper(base, py);
188
Base::PyObjectBase::PyDestructor(py);
191
PyObject* createPyObject(Base::BaseClass* base)
193
PyObject* py = base->getPyObject();
195
if (PyObject_TypeCheck(py, &Base::PyObjectBase::Type)) {
196
// if the Python wrapper is a sub-class of PyObjectBase then
197
// check if the C++ object must be added to the list of tracked objects
198
Base::PyObjectBase* pybase = static_cast<Base::PyObjectBase*>(py);
199
if (base == pybase->getTwinPointer()) {
200
// steal a reference because at this point the counter is at 2
202
Py_TYPE(py)->tp_dealloc = deallocPyObject;
203
Base::BindingManager::instance().registerWrapper(base, py);
206
// The Python wrapper creates its own copy of the C++ object
211
// if the Python wrapper is not a sub-class of PyObjectBase then
212
// immediately destroy the C++ object
220
PyObject* TypePy::createInstance(PyObject* args)
222
if (!PyArg_ParseTuple(args, "")) {
226
Py::String name(getBaseTypePtr()->getName());
227
Py::TupleN tuple(name);
229
return createInstanceByName(tuple.ptr());
232
PyObject* TypePy::createInstanceByName(PyObject* args)
235
PyObject* load = Py_False; // NOLINT
236
if (!PyArg_ParseTuple(args, "s|O!", &name, &PyBool_Type, &load)) {
240
bool loadModule = Base::asBoolean(load);
242
Base::Type::getTypeIfDerivedFrom(name, Base::BaseClass::getClassTypeId(), loadModule);
247
void* typeInstance = type.createInstance();
252
Base::BaseClass* base = static_cast<Base::BaseClass*>(typeInstance);
254
return createPyObject(base);
257
Py::String TypePy::getName() const
259
return {std::string(getBaseTypePtr()->getName())};
262
Py::Long TypePy::getKey() const
264
return Py::Long(static_cast<long>(getBaseTypePtr()->getKey()));
267
Py::String TypePy::getModule() const
269
std::string module(getBaseTypePtr()->getName());
270
std::string::size_type pos = module.find_first_of("::");
272
if (pos != std::string::npos) {
273
module = std::string(module, 0, pos);
282
PyObject* TypePy::getCustomAttributes(const char* /*attr*/) const
287
int TypePy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)