diff --git a/src/App/DocumentObjectPyImp.cpp b/src/App/DocumentObjectPyImp.cpp index 07344d2e93..701da74b56 100644 --- a/src/App/DocumentObjectPyImp.cpp +++ b/src/App/DocumentObjectPyImp.cpp @@ -100,14 +100,8 @@ PyObject* DocumentObjectPy::addProperty(PyObject *args, PyObject *kwd) // enum support auto* propEnum = dynamic_cast(prop); - if (propEnum) { - if (enumVals && PySequence_Check(enumVals)) { - std::vector enumValsAsVector; - for (Py_ssize_t i = 0; i < PySequence_Length(enumVals); ++i) { - enumValsAsVector.emplace_back(PyUnicode_AsUTF8(PySequence_GetItem(enumVals,i))); - } - propEnum->setEnums(enumValsAsVector); - } + if (propEnum && enumVals) { + propEnum->setPyObject(enumVals); } return Py::new_reference_to(this); diff --git a/src/App/DocumentPyImp.cpp b/src/App/DocumentPyImp.cpp index 7679be66cf..a084a94338 100644 --- a/src/App/DocumentPyImp.cpp +++ b/src/App/DocumentPyImp.cpp @@ -70,14 +70,8 @@ PyObject* DocumentPy::addProperty(PyObject *args, PyObject *kwd) // enum support auto* propEnum = dynamic_cast(prop); - if (propEnum) { - if (enumVals && PySequence_Check(enumVals)) { - std::vector enumValsAsVector; - for (Py_ssize_t i = 0; i < PySequence_Length(enumVals); ++i) { - enumValsAsVector.emplace_back(PyUnicode_AsUTF8(PySequence_GetItem(enumVals,i))); - } - propEnum->setEnums(enumValsAsVector); - } + if (propEnum && enumVals) { + propEnum->setPyObject(enumVals); } return Py::new_reference_to(this); diff --git a/src/App/PropertyContainerPyImp.cpp b/src/App/PropertyContainerPyImp.cpp index 083adb27c8..28446c0eeb 100644 --- a/src/App/PropertyContainerPyImp.cpp +++ b/src/App/PropertyContainerPyImp.cpp @@ -217,10 +217,10 @@ static const std::map &getStatusMap() { return statusMap; } -PyObject* PropertyContainerPy::setPropertyStatus(PyObject *args) +PyObject* PropertyContainerPy::setPropertyStatus(PyObject *args) { - char* name; - PyObject *pyValue; + char* name {}; + PyObject* pyValue {}; if (!PyArg_ParseTuple(args, "sO", &name, &pyValue)) return nullptr; @@ -232,47 +232,51 @@ PyObject* PropertyContainerPy::setPropertyStatus(PyObject *args) auto linkProp = Base::freecad_dynamic_cast(prop); std::bitset<32> status(prop->getStatus()); - size_t count = 1; - bool isSeq = false; + + std::vector items; if (PyList_Check(pyValue) || PyTuple_Check(pyValue)) { - isSeq = true; - count = PySequence_Size(pyValue); + Py::Sequence seq(pyValue); + for (const auto& it : seq) { + items.emplace_back(it); + } + } + else { + items.emplace_back(pyValue); } - for(size_t i=0; i(Py::String(item)); - if(v.size()>1 && v[0] == '-') { + if (v.size() > 1 && v[0] == '-') { value = false; v = v.substr(1); } auto it = statusMap.find(v); - if(it == statusMap.end()) { - if(linkProp && v == "AllowPartial") { + if (it == statusMap.end()) { + if (linkProp && v == "AllowPartial") { linkProp->setAllowPartial(value); continue; } + PyErr_Format(PyExc_ValueError, "Unknown property status '%s'", v.c_str()); return nullptr; } - status.set(it->second,value); + + status.set(it->second, value); } else if (item.isNumeric()) { int v = Py::Int(item); - if(v<0) { + if (v < 0) { value = false; v = -v; } - if(v==0 || v>31) + if (v == 0 || v > 31) { PyErr_Format(PyExc_ValueError, "Status value out of range '%d'", v); - status.set(v,value); + return nullptr; + } + status.set(v, value); } else { PyErr_SetString(PyExc_TypeError, "Expects status type to be Int or String"); diff --git a/src/App/PropertyStandard.cpp b/src/App/PropertyStandard.cpp index c2d77a24e6..4395623fc2 100644 --- a/src/App/PropertyStandard.cpp +++ b/src/App/PropertyStandard.cpp @@ -844,17 +844,18 @@ void PropertyIntegerSet::setPyObject(PyObject *value) { if (PySequence_Check(value)) { - Py_ssize_t nSize = PySequence_Length(value); + Py::Sequence sequence(value); + Py_ssize_t nSize = sequence.size(); std::set values; for (Py_ssize_t i=0; iob_type->tp_name; + error += item.ptr()->ob_type->tp_name; throw Base::TypeError(error); } - values.insert(PyLong_AsLong(item)); + values.insert(PyLong_AsLong(item.ptr())); } setValues(values); diff --git a/src/Base/RotationPyImp.cpp b/src/Base/RotationPyImp.cpp index a4747ac6f1..d2683355b9 100644 --- a/src/Base/RotationPyImp.cpp +++ b/src/Base/RotationPyImp.cpp @@ -576,14 +576,18 @@ int RotationPy::setCustomAttributes(const char* attr, PyObject* obj) } } else if (strcmp(attr, "Axes") == 0) { - if (PySequence_Check(obj) && PySequence_Size(obj) == 2) { - PyObject* vec1 = PySequence_GetItem(obj, 0); - PyObject* vec2 = PySequence_GetItem(obj, 1); - if (PyObject_TypeCheck(vec1, &(VectorPy::Type)) - && PyObject_TypeCheck(vec2, &(VectorPy::Type))) { - this->getRotationPtr()->setValue(*static_cast(vec1)->getVectorPtr(), - *static_cast(vec2)->getVectorPtr()); - return 1; + if (PySequence_Check(obj)) { + Py::Sequence sequence(obj); + if (sequence.size() == 2) { + Py::Object vec1 = sequence.getItem(0); + Py::Object vec2 = sequence.getItem(1); + if (PyObject_TypeCheck(vec1.ptr(), &(VectorPy::Type)) + && PyObject_TypeCheck(vec2.ptr(), &(VectorPy::Type))) { + Base::Vector3d* pt1 = static_cast(vec1.ptr())->getVectorPtr(); + Base::Vector3d* pt2 = static_cast(vec2.ptr())->getVectorPtr(); + this->getRotationPtr()->setValue(*pt1, *pt2); + return 1; + } } } } diff --git a/src/Gui/ViewProviderPyImp.cpp b/src/Gui/ViewProviderPyImp.cpp index 2e9f49c8d5..c58086f53e 100644 --- a/src/Gui/ViewProviderPyImp.cpp +++ b/src/Gui/ViewProviderPyImp.cpp @@ -410,28 +410,28 @@ PyObject* ViewProviderPy::partialRender(PyObject* args) return nullptr; std::vector values; - if(value != Py_None) { - PyObject *item = nullptr; - Py_ssize_t nSize; - if (PyList_Check(value) || PyTuple_Check(value)) - nSize = PySequence_Size(value); - else { - item = value; - value = nullptr; - nSize = 1; + if (value != Py_None) { + std::vector pylist; + if (PyList_Check(value) || PyTuple_Check(value)) { + Py::Sequence seq(value); + for (const auto& it : seq) { + pylist.emplace_back(it); + } } - values.resize(nSize); - for (Py_ssize_t i = 0; i < nSize; ++i) { - if(value) - item = PySequence_GetItem(value, i); - if (PyUnicode_Check(item)) { - values[i] = PyUnicode_AsUTF8(item); + else { + pylist.emplace_back(value); + } + + values.reserve(pylist.size()); + for (const auto& it : pylist) { + if (it.isString()) { + values.push_back(Py::String(it)); } else { std::string error = std::string("type must be str"); error += " not, "; - error += item->ob_type->tp_name; - throw Base::TypeError(error); + error += it.ptr()->ob_type->tp_name; + throw Py::TypeError(error); } } }