diff --git a/src/App/DocumentObjectPyImp.cpp b/src/App/DocumentObjectPyImp.cpp index b14d2f3fab..6dda3c9d16 100644 --- a/src/App/DocumentObjectPyImp.cpp +++ b/src/App/DocumentObjectPyImp.cpp @@ -267,25 +267,34 @@ PyObject* DocumentObjectPy::setExpression(PyObject * args) if (Py::Object(expr).isNone()) getDocumentObjectPtr()->setExpression(p, boost::shared_ptr()); +#if PY_MAJOR_VERSION >= 3 + else if (PyUnicode_Check(expr)) { + const char * exprStr = PyUnicode_AsUTF8(expr); +#else else if (PyString_Check(expr)) { const char * exprStr = PyString_AsString(expr); +#endif boost::shared_ptr shared_expr(ExpressionParser::parse(getDocumentObjectPtr(), exprStr)); getDocumentObjectPtr()->setExpression(p, shared_expr, comment); } else if (PyUnicode_Check(expr)) { +#if PY_MAJOR_VERSION >= 3 + std::string exprStr = PyUnicode_AsUTF8(expr); +#else PyObject* unicode = PyUnicode_AsEncodedString(expr, "utf-8", 0); if (unicode) { std::string exprStr = PyString_AsString(unicode); - Py_DECREF(unicode); boost::shared_ptr shared_expr(ExpressionParser::parse(getDocumentObjectPtr(), exprStr.c_str())); getDocumentObjectPtr()->setExpression(p, shared_expr, comment); + Py_DECREF(unicode); } else { // utf-8 encoding failed return 0; } +#endif } else throw Py::TypeError("String or None expected."); diff --git a/src/App/DocumentPyImp.cpp b/src/App/DocumentPyImp.cpp index dccaff2e77..d69f4e6958 100644 --- a/src/App/DocumentPyImp.cpp +++ b/src/App/DocumentPyImp.cpp @@ -211,7 +211,11 @@ PyObject* DocumentPy::exportGraphviz(PyObject * args) else { std::stringstream str; getDocumentPtr()->exportGraphviz(str); +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromString(str.str().c_str()); +#else return PyString_FromString(str.str().c_str()); +#endif } } @@ -326,6 +330,13 @@ PyObject* DocumentPy::openTransaction(PyObject *args) if (!PyArg_ParseTuple(args, "|O",&value)) return NULL; // NULL triggers exception std::string cmd; + + +#if PY_MAJOR_VERSION >= 3 + if (PyUnicode_Check(value)) { + cmd = PyUnicode_AsUTF8(value); + } +#else if (PyUnicode_Check(value)) { PyObject* unicode = PyUnicode_AsLatin1String(value); cmd = PyString_AsString(unicode); @@ -334,7 +345,10 @@ PyObject* DocumentPy::openTransaction(PyObject *args) else if (PyString_Check(value)) { cmd = PyString_AsString(value); } - getDocumentPtr()->openTransaction(cmd.c_str()); +#endif + else + return NULL; + getDocumentPtr()->openTransaction(cmd.c_str()); Py_Return; } @@ -521,9 +535,10 @@ Py::Int DocumentPy::getUndoMode(void) const void DocumentPy::setUndoMode(Py::Int arg) { - getDocumentPtr()->setUndoMode(arg); + getDocumentPtr()->setUndoMode(arg); } + Py::Int DocumentPy::getUndoRedoMemSize(void) const { return Py::Int((long)getDocumentPtr()->getUndoMemSize()); @@ -591,12 +606,16 @@ PyObject* DocumentPy::getTempFileName(PyObject *args) std::string string; if (PyUnicode_Check(value)) { +#if PY_MAJOR_VERSION >= 3 + string = PyUnicode_AsUTF8(value); +#else PyObject* unicode = PyUnicode_AsUTF8String(value); string = PyString_AsString(unicode); Py_DECREF(unicode); } else if (PyString_Check(value)) { string = PyString_AsString(value); +#endif } else { std::string error = std::string("type must be a string!"); diff --git a/src/App/FeaturePythonPyImp.h b/src/App/FeaturePythonPyImp.h index d040ea01b6..47fafa6f92 100644 --- a/src/App/FeaturePythonPyImp.h +++ b/src/App/FeaturePythonPyImp.h @@ -37,6 +37,29 @@ virtual ~_class_(); \ }; +#if PY_MAJOR_VERSION >= 3 +#define PYTHON_TYPE_IMP(_class_, _subclass_) \ + PyTypeObject _class_::Type = { \ + PyVarObject_HEAD_INIT(&PyType_Type, 0) \ + ""#_class_"", \ + sizeof(_class_), \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ + Py_TPFLAGS_BASETYPE|Py_TPFLAGS_DEFAULT, \ + ""#_class_"", \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, \ + &_subclass_::Type, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \ + }; \ + _class_::_class_(Base::BaseClass *pcObject, PyTypeObject *T) \ + : _subclass_(reinterpret_cast<_subclass_::PointerType>(pcObject), T) \ + { \ + } \ + _class_::~_class_() \ + { \ + } + +#else + #define PYTHON_TYPE_IMP(_class_, _subclass_) \ PyTypeObject _class_::Type = { \ PyObject_HEAD_INIT(&PyType_Type) \ @@ -58,6 +81,8 @@ { \ } +#endif + namespace App { diff --git a/src/App/ObjectIdentifier.cpp b/src/App/ObjectIdentifier.cpp index 9712220c71..b7b51ce3ef 100644 --- a/src/App/ObjectIdentifier.cpp +++ b/src/App/ObjectIdentifier.cpp @@ -1035,18 +1035,28 @@ boost::any ObjectIdentifier::getValue() const if (!pyvalue) throw Base::RuntimeError("Failed to get property value."); - +#if PY_MAJOR_VERSION < 3 if (PyInt_Check(pyvalue)) return boost::any(PyInt_AsLong(pyvalue)); +#else + if (PyLong_Check(pyvalue)) + return boost::any(PyLong_AsLong(pyvalue)); +#endif else if (PyFloat_Check(pyvalue)) return boost::any(PyFloat_AsDouble(pyvalue)); +#if PY_MAJOR_VERSION < 3 else if (PyString_Check(pyvalue)) return boost::any(PyString_AsString(pyvalue)); +#endif else if (PyUnicode_Check(pyvalue)) { PyObject * s = PyUnicode_AsUTF8String(pyvalue); destructor d2(s); +#if PY_MAJOR_VERSION >= 3 + return boost::any(PyUnicode_AsUTF8(s)); +#else return boost::any(PyString_AsString(s)); +#endif } else if (PyObject_TypeCheck(pyvalue, &Base::QuantityPy::Type)) { Base::QuantityPy * qp = static_cast(pyvalue); diff --git a/src/App/PropertyContainerPyImp.cpp b/src/App/PropertyContainerPyImp.cpp index 3fed9a4fa1..6ff2a4e6c8 100644 --- a/src/App/PropertyContainerPyImp.cpp +++ b/src/App/PropertyContainerPyImp.cpp @@ -244,7 +244,11 @@ PyObject *PropertyContainerPy::getCustomAttributes(const char* attr) const PyObject *dict = PyDict_New(); if (dict) { for ( std::map::iterator it = Map.begin(); it != Map.end(); ++it ) +#if PY_MAJOR_VERSION >= 3 + PyDict_SetItem(dict, PyUnicode_FromString(it->first.c_str()), PyUnicode_FromString("")); +#else PyDict_SetItem(dict, PyString_FromString(it->first.c_str()), PyString_FromString("")); +#endif if (PyErr_Occurred()) { Py_DECREF(dict); dict = NULL; diff --git a/src/App/PropertyFile.cpp b/src/App/PropertyFile.cpp index 1be0b2c60c..cf34b69b06 100644 --- a/src/App/PropertyFile.cpp +++ b/src/App/PropertyFile.cpp @@ -253,8 +253,55 @@ PyObject *PropertyFileIncluded::getPyObject(void) return p; } +#if PY_MAJOR_VERSION >= 3 +namespace App { +const char* getNameFromFile(PyObject* value) +{ + const char* string = 0; + PyObject *oname = PyObject_GetAttrString (value, "name"); + if (oname) { + if (PyUnicode_Check (oname)) { + string = PyUnicode_AsUTF8 (oname); + } + else if (PyBytes_Check (oname)) { + string = PyBytes_AsString (oname); + } + Py_DECREF (oname); + } + + if (!string) + throw Base::TypeError("Unable to get filename"); + return string; +} + + + +bool isIOFile(PyObject* file) +{ + PyObject* io = PyImport_ImportModule("io"); + PyObject* IOBase_Class = PyObject_GetAttrString(io, "IOBase"); + bool isFile = PyObject_IsInstance(file, IOBase_Class); + Py_DECREF(IOBase_Class); + Py_DECREF(io); + return isFile; +} +} +#endif + void PropertyFileIncluded::setPyObject(PyObject *value) { +#if PY_MAJOR_VERSION >= 3 + std::string string; + if (PyUnicode_Check(value)) { + string = PyUnicode_AsUTF8(value); + } + else if (PyBytes_Check(value)) { + string = PyBytes_AsString(value); + } + else if (isIOFile(value)){ + string = getNameFromFile(value); + } +#else std::string string; if (PyUnicode_Check(value)) { PyObject* unicode = PyUnicode_AsUTF8String(value); @@ -268,6 +315,7 @@ void PropertyFileIncluded::setPyObject(PyObject *value) PyObject* FileName = PyFile_Name(value); string = PyString_AsString(FileName); } +#endif else if (PyTuple_Check(value)) { if (PyTuple_Size(value) != 2) throw Base::TypeError("Tuple needs size of (filePath,newFileName)"); @@ -276,6 +324,17 @@ void PropertyFileIncluded::setPyObject(PyObject *value) // decoding file std::string fileStr; +#if PY_MAJOR_VERSION >= 3 + if (PyUnicode_Check(file)) { + fileStr = PyUnicode_AsUTF8(file); + } + else if (PyBytes_Check(file)) { + fileStr = PyBytes_AsString(file); + } + else if (isIOFile(value)) { + fileStr = getNameFromFile(file); + } +#else if (PyUnicode_Check(file)) { PyObject* unicode = PyUnicode_AsUTF8String(file); fileStr = PyString_AsString(unicode); @@ -288,6 +347,7 @@ void PropertyFileIncluded::setPyObject(PyObject *value) PyObject* FileName = PyFile_Name(file); fileStr = PyString_AsString(FileName); } +#endif else { std::string error = std::string("First item in tuple must be a file or string, not "); error += file->ob_type->tp_name; @@ -296,6 +356,17 @@ void PropertyFileIncluded::setPyObject(PyObject *value) // decoding name std::string nameStr; +#if PY_MAJOR_VERSION >= 3 + if (PyUnicode_Check(name)) { + nameStr = PyUnicode_AsUTF8(name); + } + else if (PyBytes_Check(name)) { + nameStr = PyBytes_AsString(name); + } + else if (isIOFile(value)) { + nameStr = getNameFromFile(name); + } +#else if (PyString_Check(name)) { nameStr = PyString_AsString(name); } @@ -303,6 +374,7 @@ void PropertyFileIncluded::setPyObject(PyObject *value) PyObject* FileName = PyFile_Name(name); nameStr = PyString_AsString(FileName); } +#endif else { std::string error = std::string("Second item in tuple must be a string, not "); error += name->ob_type->tp_name; diff --git a/src/App/PropertyGeo.cpp b/src/App/PropertyGeo.cpp index 48883789d7..1faed23468 100644 --- a/src/App/PropertyGeo.cpp +++ b/src/App/PropertyGeo.cpp @@ -115,24 +115,39 @@ void PropertyVector::setPyObject(PyObject *value) item = PyTuple_GetItem(value,0); if (PyFloat_Check(item)) cVec.x = PyFloat_AsDouble(item); +#if PY_MAJOR_VERSION < 3 else if (PyInt_Check(item)) cVec.x = (double)PyInt_AsLong(item); +#else + else if (PyLong_Check(item)) + cVec.x = (double)PyLong_AsLong(item); +#endif else throw Base::TypeError("Not allowed type used in tuple (float expected)..."); // y item = PyTuple_GetItem(value,1); if (PyFloat_Check(item)) cVec.y = PyFloat_AsDouble(item); +#if PY_MAJOR_VERSION < 3 else if (PyInt_Check(item)) cVec.y = (double)PyInt_AsLong(item); +#else + else if (PyLong_Check(item)) + cVec.y = (double)PyLong_AsLong(item); +#endif else throw Base::TypeError("Not allowed type used in tuple (float expected)..."); // z item = PyTuple_GetItem(value,2); if (PyFloat_Check(item)) cVec.z = PyFloat_AsDouble(item); +#if PY_MAJOR_VERSION < 3 else if (PyInt_Check(item)) cVec.z = (double)PyInt_AsLong(item); +#else + else if (PyLong_Check(item)) + cVec.z = (double)PyLong_AsLong(item); +#endif else throw Base::TypeError("Not allowed type used in tuple (float expected)..."); setValue( cVec ); @@ -433,8 +448,13 @@ void PropertyMatrix::setPyObject(PyObject *value) item = PyTuple_GetItem(value,x+y*4); if (PyFloat_Check(item)) cMatrix[x][y] = PyFloat_AsDouble(item); +#if PY_MAJOR_VERSION < 3 else if (PyInt_Check(item)) cMatrix[x][y] = (double)PyInt_AsLong(item); +#else + else if (PyLong_Check(item)) + cMatrix[x][y] = (double)PyLong_AsLong(item); +#endif else throw Base::TypeError("Not allowed type used in matrix tuple (a number expected)..."); } diff --git a/src/App/PropertyPythonObject.cpp b/src/App/PropertyPythonObject.cpp index 9ca6b4df58..45897980d5 100644 --- a/src/App/PropertyPythonObject.cpp +++ b/src/App/PropertyPythonObject.cpp @@ -325,10 +325,14 @@ void PropertyPythonObject::Restore(Base::XMLReader &reader) if (reader.hasAttribute("module") && reader.hasAttribute("class")) { Py::Module mod(PyImport_ImportModule(reader.getAttribute("module")),true); PyObject* cls = mod.getAttr(reader.getAttribute("class")).ptr(); +#if PY_MAJOR_VERSION >= 3 + if (PyType_Check(cls)) { +#else if (PyClass_Check(cls)) { this->object = PyInstance_NewRaw(cls, 0); } else if (PyType_Check(cls)) { +#endif this->object = PyType_GenericAlloc((PyTypeObject*)cls, 0); } else { @@ -340,7 +344,11 @@ void PropertyPythonObject::Restore(Base::XMLReader &reader) std::string nam = std::string(what[1].first, what[1].second); std::string cls = std::string(what[2].first, what[2].second); Py::Module mod(PyImport_ImportModule(nam.c_str()),true); +#if PY_MAJOR_VERSION >= 3 + this->object = PyObject_CallObject(mod.getAttr(cls).ptr(), NULL); +#else this->object = PyInstance_NewRaw(mod.getAttr(cls).ptr(), 0); +#endif load_pickle = true; buffer = std::string(what[2].second, end); } diff --git a/src/App/PropertyStandard.cpp b/src/App/PropertyStandard.cpp index 57ca2af33d..1c3c3af7db 100644 --- a/src/App/PropertyStandard.cpp +++ b/src/App/PropertyStandard.cpp @@ -94,9 +94,15 @@ PyObject *PropertyInteger::getPyObject(void) void PropertyInteger::setPyObject(PyObject *value) { +#if PY_MAJOR_VERSION < 3 if (PyInt_Check(value)) { aboutToSetValue(); _lValue = PyInt_AsLong(value); +#else + if (PyLong_Check(value)) { + aboutToSetValue(); + _lValue = PyLong_AsLong(value); +#endif hasSetValue(); } else { @@ -221,12 +227,16 @@ void PropertyPath::setPyObject(PyObject *value) { std::string path; if (PyUnicode_Check(value)) { +#if PY_MAJOR_VERSION >= 3 + path = PyUnicode_AsUTF8(value); +#else PyObject* unicode = PyUnicode_AsUTF8String(value); path = PyString_AsString(unicode); Py_DECREF(unicode); } else if (PyString_Check(value)) { path = PyString_AsString(value); +#endif } else { std::string error = std::string("type must be str or unicode, not "); @@ -419,15 +429,48 @@ PyObject * PropertyEnumeration::getPyObject(void) } void PropertyEnumeration::setPyObject(PyObject *value) -{ +{ +#if PY_MAJOR_VERSION < 3 if (PyInt_Check(value)) { long val = PyInt_AsLong(value); +#else + if (PyLong_Check(value)) { + long val = PyLong_AsLong(value); +#endif if (_enum.isValid()) { aboutToSetValue(); _enum.setValue(val, true); hasSetValue(); } } + else if (PyUnicode_Check(value)) { +#if PY_MAJOR_VERSION >= 3 + const char* str = PyUnicode_AsUTF8 (value); + if (_enum.contains(str)) { + aboutToSetValue(); + _enum.setValue(PyUnicode_AsUTF8 (value)); + hasSetValue(); + } + else { + std::stringstream out; + out << "'" << str << "' is not part of the enumeration"; + throw Base::ValueError(out.str()); + } +#else + PyObject* unicode = PyUnicode_AsUTF8String(value); + const char* str = PyString_AsString (unicode); + if (_enum.contains(str)) { + aboutToSetValue(); + _enum.setValue(PyString_AsString (unicode)); + hasSetValue(); + } + else { + std::stringstream out; + out << "'" << str << "' is not part of the enumeration"; + throw Base::ValueError(out.str()); + } + Py_DECREF(unicode); + } else if (PyString_Check(value)) { const char* str = PyString_AsString (value); if (_enum.contains(str)) { @@ -440,11 +483,16 @@ void PropertyEnumeration::setPyObject(PyObject *value) out << "'" << str << "' is not part of the enumeration"; throw Base::ValueError(out.str()); } +#endif } else if (PyUnicode_Check(value)) { +#if PY_MAJOR_VERSION >=3 + std::string str = PyUnicode_AsUTF8(value); +#else PyObject* unicode = PyUnicode_AsUTF8String(value); std::string str = PyString_AsString(unicode); Py_DECREF(unicode); +#endif if (_enum.contains(str.c_str())) { aboutToSetValue(); _enum.setValue(str); @@ -464,20 +512,25 @@ void PropertyEnumeration::setPyObject(PyObject *value) for (Py_ssize_t i = 0; i < nSize; ++i) { PyObject *item = PySequence_GetItem(value, i); - if (PyString_Check(item)) { - values[i] = PyString_AsString(item); - } - else if (PyUnicode_Check(item)) { + if (PyUnicode_Check(item)) { +#if PY_MAJOR_VERSION >= 3 + values[i] = PyUnicode_AsUTF8(item); +#else PyObject* unicode = PyUnicode_AsUTF8String(item); values[i] = PyString_AsString(unicode); Py_DECREF(unicode); +#endif } +#if PY_MAJOR_VERSION < 3 + if (PyString_Check(item)) { + values[i] = PyString_AsString(item); + } +#endif else { std::string error = std::string("type in list must be str or unicode, not "); throw Base::TypeError(error + item->ob_type->tp_name); } } - _enum.setEnums(values); setValue((long)0); } @@ -556,9 +609,14 @@ const PropertyIntegerConstraint::Constraints* PropertyIntegerConstraint::getCon } void PropertyIntegerConstraint::setPyObject(PyObject *value) -{ +{ +#if PY_MAJOR_VERSION < 3 if (PyInt_Check(value)) { long temp = PyInt_AsLong(value); +#else + if (PyLong_Check(value)) { + long temp = PyLong_AsLong(value); +#endif if (_ConstStruct) { if (temp > _ConstStruct->UpperBound) temp = _ConstStruct->UpperBound; @@ -575,8 +633,13 @@ void PropertyIntegerConstraint::setPyObject(PyObject *value) for (int i=0; i<4; i++) { PyObject* item; item = PyTuple_GetItem(value,i); +#if PY_MAJOR_VERSION < 3 if (PyInt_Check(item)) values[i] = PyInt_AsLong(item); +#else + if (PyLong_Check(item)) + values[i] = PyLong_AsLong(item); +#endif else throw Base::TypeError("Type in tuple must be int"); } @@ -682,7 +745,11 @@ PyObject *PropertyIntegerList::getPyObject(void) { PyObject* list = PyList_New(getSize()); for(int i = 0;iob_type->tp_name; throw Base::TypeError(error); } values[i] = PyInt_AsLong(item); +#else + if (!PyLong_Check(item)) { + std::string error = std::string("type in list must be int, not "); + error += item->ob_type->tp_name; + throw Base::TypeError(error); + } + values[i] = PyLong_AsLong(item); +#endif } setValues(values); } +#if PY_MAJOR_VERSION < 3 else if (PyInt_Check(value)) { setValue(PyInt_AsLong(value)); +#else + else if (PyLong_Check(value)) { + setValue(PyLong_AsLong(value)); +#endif } else { std::string error = std::string("type must be int or a sequence of int, not "); @@ -810,7 +891,11 @@ PyObject *PropertyIntegerSet::getPyObject(void) { PyObject* set = PySet_New(NULL); for(std::set::const_iterator it=_lValueSet.begin();it!=_lValueSet.end();++it) +#if PY_MAJOR_VERSION < 3 PySet_Add(set,PyInt_FromLong(*it)); +#else + PySet_Add(set,PyLong_FromLong(*it)); +#endif return set; } @@ -823,18 +908,32 @@ void PropertyIntegerSet::setPyObject(PyObject *value) for (Py_ssize_t i=0; iob_type->tp_name; throw Base::TypeError(error); } values.insert(PyInt_AsLong(item)); +#else + if (!PyLong_Check(item)) { + std::string error = std::string("type in list must be int, not "); + error += item->ob_type->tp_name; + throw Base::TypeError(error); + } + values.insert(PyLong_AsLong(item)); +#endif } setValues(values); } +#if PY_MAJOR_VERSION < 3 else if (PyInt_Check(value)) { setValue(PyInt_AsLong(value)); +#else + else if (PyLong_Check(value)) { + setValue(PyLong_AsLong(value)); +#endif } else { std::string error = std::string("type must be int or list of int, not "); @@ -941,9 +1040,15 @@ void PropertyFloat::setPyObject(PyObject *value) _dValue = PyFloat_AsDouble(value); hasSetValue(); } +#if PY_MAJOR_VERSION < 3 else if(PyInt_Check(value)) { aboutToSetValue(); _dValue = PyInt_AsLong(value); +#else + else if(PyLong_Check(value)) { + aboutToSetValue(); + _dValue = PyLong_AsLong(value); +#endif hasSetValue(); } else { @@ -1045,8 +1150,13 @@ void PropertyFloatConstraint::setPyObject(PyObject *value) _dValue = temp; hasSetValue(); } +#if PY_MAJOR_VERSION < 3 else if (PyInt_Check(value)) { double temp = (double)PyInt_AsLong(value); +#else + else if (PyLong_Check(value)) { + double temp = (double)PyLong_AsLong(value); +#endif if (_ConstStruct) { if (temp > _ConstStruct->UpperBound) temp = _ConstStruct->UpperBound; @@ -1065,8 +1175,13 @@ void PropertyFloatConstraint::setPyObject(PyObject *value) item = PyTuple_GetItem(value,i); if (PyFloat_Check(item)) values[i] = PyFloat_AsDouble(item); +#if PY_MAJOR_VERSION < 3 else if (PyInt_Check(item)) values[i] = PyInt_AsLong(item); +#else + else if (PyLong_Check(item)) + values[i] = PyLong_AsLong(item); +#endif else throw Base::TypeError("Type in tuple must be float or int"); } @@ -1186,7 +1301,7 @@ void PropertyFloatList::setPyObject(PyObject *value) PyObject* item = PyList_GetItem(value, i); if (PyFloat_Check(item)) { values[i] = PyFloat_AsDouble(item); -#if PYTHON_VERSION_MAJOR >= 3 +#if PY_MAJOR_VERSION >= 3 } else if (PyLong_Check(item)) { values[i] = static_cast(PyLong_AsLong(item)); #else @@ -1346,12 +1461,16 @@ void PropertyString::setPyObject(PyObject *value) { std::string string; if (PyUnicode_Check(value)) { +#if PY_MAJOR_VERSION >= 3 + string = PyUnicode_AsUTF8(value); +#else PyObject* unicode = PyUnicode_AsUTF8String(value); string = PyString_AsString(unicode); Py_DECREF(unicode); } else if (PyString_Check(value)) { string = PyString_AsString(value); +#endif } else { std::string error = std::string("type must be str or unicode, not "); @@ -1459,18 +1578,31 @@ const Base::Uuid& PropertyUUID::getValue(void) const PyObject *PropertyUUID::getPyObject(void) { +#if PY_MAJOR_VERSION >= 3 + PyObject *p = PyUnicode_FromString(_uuid.getValue().c_str()); +#else PyObject *p = PyString_FromString(_uuid.getValue().c_str()); +#endif return p; } void PropertyUUID::setPyObject(PyObject *value) { std::string string; - if (PyString_Check(value)) { + if (PyUnicode_Check(value)) { +#if PY_MAJOR_VERSION >= 3 + string = PyUnicode_AsUTF8(value); +#else + PyObject* unicode = PyUnicode_AsUTF8String(value); + string = PyString_AsString(unicode); + Py_DECREF(unicode); + } + else if (PyString_Check(value)) { string = PyString_AsString(value); +#endif } else { - std::string error = std::string("type must be a str, not "); + std::string error = std::string("type must be unicode or str, not "); error += value->ob_type->tp_name; throw Base::TypeError(error); } @@ -1604,9 +1736,15 @@ PyObject *PropertyStringList::getPyObject(void) void PropertyStringList::setPyObject(PyObject *value) { +#if PY_MAJOR_VERSION >=3 + if (PyBytes_Check(value)) { + setValue(PyBytes_AsString(value)); + } +#else if (PyString_Check(value)) { setValue(PyString_AsString(value)); } +#endif else if (PySequence_Check(value)) { Py_ssize_t nSize = PySequence_Size(value); std::vector values; @@ -1615,12 +1753,16 @@ void PropertyStringList::setPyObject(PyObject *value) for (Py_ssize_t i=0; i= 3 + values[i] = PyUnicode_AsUTF8(item); +#else PyObject* unicode = PyUnicode_AsUTF8String(item); values[i] = PyString_AsString(unicode); Py_DECREF(unicode); } else if (PyString_Check(item)) { values[i] = PyString_AsString(item); +#endif } else { std::string error = std::string("type in list must be str or unicode, not "); @@ -1631,8 +1773,18 @@ void PropertyStringList::setPyObject(PyObject *value) setValues(values); } + else if (PyUnicode_Check(value)) { +#if PY_MAJOR_VERSION >= 3 + setValue(PyUnicode_AsUTF8(value)); + } +#else + PyObject* unicode = PyUnicode_AsUTF8String(value); + setValue(PyString_AsString(unicode)); + Py_DECREF(unicode); + } +#endif else { - std::string error = std::string("type must be str or list of str, not "); + std::string error = std::string("type must be str or unicode or list of str or list of unicodes, not "); error += value->ob_type->tp_name; throw Base::TypeError(error); } @@ -1776,11 +1928,20 @@ void PropertyMap::setPyObject(PyObject *value) // check on the key: std::string keyStr; PyObject* key = PyList_GetItem(keyList, i); + if (PyUnicode_Check(key)) { +#if PY_MAJOR_VERSION >= 3 + keyStr = PyUnicode_AsUTF8(key); +#else + PyObject* unicode = PyUnicode_AsUTF8String(key); + keyStr = PyString_AsString(unicode); + Py_DECREF(unicode); + } if (PyString_Check(key)) { keyStr = PyString_AsString(key); +#endif } else { - std::string error = std::string("type of the key need to be a string, not"); + std::string error = std::string("type of the key need to be unicode or string, not"); error += key->ob_type->tp_name; throw Base::TypeError(error); } @@ -1788,12 +1949,16 @@ void PropertyMap::setPyObject(PyObject *value) // check on the item: PyObject* item = PyList_GetItem(itemList, i); if (PyUnicode_Check(item)) { +#if PY_MAJOR_VERSION >= 3 + values[keyStr] = PyUnicode_AsUTF8(item); +#else PyObject* unicode = PyUnicode_AsUTF8String(item); values[keyStr] = PyString_AsString(unicode); Py_DECREF(unicode); } else if (PyString_Check(item)) { values[keyStr] = PyString_AsString(item); +#endif } else { std::string error = std::string("type in list must be string or unicode, not "); @@ -1912,8 +2077,13 @@ void PropertyBool::setPyObject(PyObject *value) { if (PyBool_Check(value)) setValue(PyObject_IsTrue(value)!=0); +#if PY_MAJOR_VERSION < 3 else if(PyInt_Check(value)) setValue(PyInt_AsLong(value)!=0); +#else + else if(PyLong_Check(value)) + setValue(PyLong_AsLong(value)!=0); +#endif else { std::string error = std::string("type must be bool, not "); error += value->ob_type->tp_name; @@ -2052,8 +2222,20 @@ PyObject *PropertyBoolList::getPyObject(void) void PropertyBoolList::setPyObject(PyObject *value) { // string is also a sequence and must be be treated differently + std::string str; + if (PyUnicode_Check(value)) { +#if PY_MAJOR_VERSION >= 3 + str = PyUnicode_AsUTF8(value); +#else + PyObject* unicode = PyUnicode_AsUTF8String(value); + str = PyString_AsString(unicode); + Py_DECREF(unicode); + boost::dynamic_bitset<> values(str); + setValues(values); + } if (PyString_Check(value)) { - std::string str = PyString_AsString(value); + str = PyString_AsString(value); +#endif boost::dynamic_bitset<> values(str); setValues(values); } @@ -2066,8 +2248,13 @@ void PropertyBoolList::setPyObject(PyObject *value) if (PyBool_Check(item)) { values[i] = (PyObject_IsTrue(item) ? true : false); } +#if PY_MAJOR_VERSION < 3 else if (PyInt_Check(item)) { values[i] = (PyInt_AsLong(item) ? true : false); +#else + else if (PyLong_Check(item)) { + values[i] = (PyLong_AsLong(item) ? true : false); +#endif } else { std::string error = std::string("type in list must be bool or int, not "); @@ -2081,8 +2268,13 @@ void PropertyBoolList::setPyObject(PyObject *value) else if (PyBool_Check(value)) { setValue(PyObject_IsTrue(value) ? true : false); } +#if PY_MAJOR_VERSION < 3 else if (PyInt_Check(value)) { setValue(PyInt_AsLong(value) ? true : false); +#else + else if (PyLong_Check(value)) { + setValue(PyLong_AsLong(value) ? true : false); +#endif } else { std::string error = std::string("type must be bool or a sequence of bool, not "); diff --git a/src/App/PropertyUnits.cpp b/src/App/PropertyUnits.cpp index 12243db655..f757349d9d 100644 --- a/src/App/PropertyUnits.cpp +++ b/src/App/PropertyUnits.cpp @@ -75,19 +75,29 @@ Base::Quantity PropertyQuantity::createQuantityFromPy(PyObject *value) { Base::Quantity quant; - if (PyString_Check(value)) - quant = Quantity::parse(QString::fromLatin1(PyString_AsString(value))); - else if (PyUnicode_Check(value)){ + if (PyUnicode_Check(value)){ +#if PY_MAJOR_VERSION >= 3 + quant = Quantity::parse(QString::fromUtf8(PyUnicode_AsUTF8(value))); + } +#else PyObject* unicode = PyUnicode_AsUTF8String(value); std::string Str; Str = PyString_AsString(unicode); quant = Quantity::parse(QString::fromUtf8(Str.c_str())); Py_DECREF(unicode); } + else if (PyString_Check(value)) + quant = Quantity::parse(QString::fromLatin1(PyString_AsString(value))); +#endif else if (PyFloat_Check(value)) quant = Quantity(PyFloat_AsDouble(value),_Unit); +#if PY_MAJOR_VERSION < 3 else if (PyInt_Check(value)) quant = Quantity((double)PyInt_AsLong(value),_Unit); +#else + else if (PyLong_Check(value)) + quant = Quantity((double)PyLong_AsLong(value),_Unit); +#endif else if (PyObject_TypeCheck(value, &(QuantityPy::Type))) { Base::QuantityPy *pcObject = static_cast(value); quant = *(pcObject->getQuantityPtr());