From 17031e2a241dfaa6cd99cd249f3aa0336fbc4914 Mon Sep 17 00:00:00 2001 From: Peter Lama Date: Thu, 15 Jun 2017 16:38:22 -0400 Subject: [PATCH] Path: py3 fixes Needed for unit tests to pass --- src/Mod/Path/App/CommandPyImp.cpp | 73 +++++++++++-------- src/Mod/Path/App/PathPyImp.cpp | 2 +- src/Mod/Path/PathScripts/PathLoadTool.py | 4 +- src/Mod/Path/PathScripts/PathPostProcessor.py | 16 +++- src/Mod/Path/PathScripts/PathSelection.py | 2 +- .../PathScripts/PathToolLibraryManager.py | 2 +- src/Mod/Path/PathScripts/PathUtils.py | 2 +- 7 files changed, 62 insertions(+), 39 deletions(-) diff --git a/src/Mod/Path/App/CommandPyImp.cpp b/src/Mod/Path/App/CommandPyImp.cpp index 2b19863647..6d302af130 100644 --- a/src/Mod/Path/App/CommandPyImp.cpp +++ b/src/Mod/Path/App/CommandPyImp.cpp @@ -74,19 +74,20 @@ int CommandPy::PyInit(PyObject* args, PyObject* kwd) PyObject *key, *value; Py_ssize_t pos = 0; while (parameters && PyDict_Next(parameters, &pos, &key, &value)) { + std::string ckey; #if PY_MAJOR_VERSION >= 3 - if ( !PyObject_TypeCheck(key,&(PyBytes_Type)) || (!PyObject_TypeCheck(value,&(PyFloat_Type)) && !PyObject_TypeCheck(value,&(PyLong_Type))) ) { + if (PyUnicode_Check(key)) { + ckey = PyUnicode_AsUTF8(key); #else - if ( !PyObject_TypeCheck(key,&(PyString_Type)) || (!PyObject_TypeCheck(value,&(PyFloat_Type)) && !PyObject_TypeCheck(value,&(PyInt_Type))) ) { + if (PyString_Check(key)) { + ckey = PyString_AsString(key); #endif - PyErr_SetString(PyExc_TypeError, "The dictionary can only contain string:number pairs"); + } + else { + PyErr_SetString(PyExc_TypeError, "The dictionary can only contain string keys"); return -1; } -#if PY_MAJOR_VERSION >= 3 - std::string ckey = PyBytes_AsString(key); -#else - std::string ckey = PyString_AsString(key); -#endif + boost::to_upper(ckey); double cvalue; #if PY_MAJOR_VERSION >= 3 @@ -96,9 +97,14 @@ int CommandPy::PyInit(PyObject* args, PyObject* kwd) if (PyObject_TypeCheck(value,&(PyInt_Type))) { cvalue = (double)PyInt_AsLong(value); #endif - } else { + } + else if (PyObject_TypeCheck(value, &(PyFloat_Type))) { cvalue = PyFloat_AsDouble(value); } + else { + PyErr_SetString(PyExc_TypeError, "The dictionary can only contain number values"); + return -1; + } getCommandPtr()->Parameters[ckey]=cvalue; } return 0; @@ -138,7 +144,7 @@ Py::Dict CommandPy::getParameters(void) const PyObject *dict = PyDict_New(); for(std::map::iterator i = getCommandPtr()->Parameters.begin(); i != getCommandPtr()->Parameters.end(); ++i) { #if PY_MAJOR_VERSION >= 3 - PyDict_SetItem(dict,PyBytes_FromString(i->first.c_str()),PyFloat_FromDouble(i->second)); + PyDict_SetItem(dict,PyUnicode_FromString(i->first.c_str()),PyFloat_FromDouble(i->second)); #else PyDict_SetItem(dict,PyString_FromString(i->first.c_str()),PyFloat_FromDouble(i->second)); #endif @@ -152,29 +158,36 @@ void CommandPy::setParameters(Py::Dict arg) PyObject *key, *value; Py_ssize_t pos = 0; while (PyDict_Next(dict_copy, &pos, &key, &value)) { + std::string ckey; #if PY_MAJOR_VERSION >= 3 - if ( PyObject_TypeCheck(key,&(PyBytes_Type)) && (PyObject_TypeCheck(value,&(PyFloat_Type)) || PyObject_TypeCheck(value,&(PyLong_Type)) ) ) { - std::string ckey = PyBytes_AsString(key); + if (PyUnicode_Check(key)) { + ckey = PyUnicode_AsUTF8(key); #else - if ( PyObject_TypeCheck(key,&(PyString_Type)) && (PyObject_TypeCheck(value,&(PyFloat_Type)) || PyObject_TypeCheck(value,&(PyInt_Type)) ) ) { - std::string ckey = PyString_AsString(key); + if (PyString_Check(key)) { + ckey = PyString_AsString(key); #endif - boost::to_upper(ckey); - double cvalue; -#if PY_MAJOR_VERSION >= 3 - if (PyObject_TypeCheck(value,&(PyLong_Type))) { - cvalue = (double)PyLong_AsLong(value); -#else - if (PyObject_TypeCheck(value,&(PyInt_Type))) { - cvalue = (double)PyInt_AsLong(value); -#endif - } else { - cvalue = PyFloat_AsDouble(value); - } - getCommandPtr()->Parameters[ckey]=cvalue; - } else { - throw Py::Exception("The dictionary can only contain string:number pairs"); } + else { + throw Py::Exception("The dictionary can only contain string keys"); + } + + boost::to_upper(ckey); + double cvalue; +#if PY_MAJOR_VERSION >= 3 + if (PyObject_TypeCheck(value,&(PyLong_Type))) { + cvalue = (double)PyLong_AsLong(value); +#else + if (PyObject_TypeCheck(value,&(PyInt_Type))) { + cvalue = (double)PyInt_AsLong(value); +#endif + } + else if (PyObject_TypeCheck(value, &(PyFloat_Type))) { + cvalue = PyFloat_AsDouble(value); + } + else { + throw Py::Exception("The dictionary can only contain number values"); + } + getCommandPtr()->Parameters[ckey]=cvalue; } } @@ -184,7 +197,7 @@ PyObject* CommandPy::toGCode(PyObject *args) { if (PyArg_ParseTuple(args, "")) { #if PY_MAJOR_VERSION >= 3 - return PyBytes_FromString(getCommandPtr()->toGCode().c_str()); + return PyUnicode_FromString(getCommandPtr()->toGCode().c_str()); #else return PyString_FromString(getCommandPtr()->toGCode().c_str()); #endif diff --git a/src/Mod/Path/App/PathPyImp.cpp b/src/Mod/Path/App/PathPyImp.cpp index 233a40ecf0..3bba29b46f 100644 --- a/src/Mod/Path/App/PathPyImp.cpp +++ b/src/Mod/Path/App/PathPyImp.cpp @@ -179,7 +179,7 @@ PyObject* PathPy::toGCode(PyObject * args) if (PyArg_ParseTuple(args, "")) { std::string result = getToolpathPtr()->toGCode(); #if PY_MAJOR_VERSION >= 3 - return PyBytes_FromString(result.c_str()); + return PyUnicode_FromString(result.c_str()); #else return PyString_FromString(result.c_str()); #endif diff --git a/src/Mod/Path/PathScripts/PathLoadTool.py b/src/Mod/Path/PathScripts/PathLoadTool.py index 5b780738c5..91b4bea985 100644 --- a/src/Mod/Path/PathScripts/PathLoadTool.py +++ b/src/Mod/Path/PathScripts/PathLoadTool.py @@ -26,12 +26,12 @@ import FreeCAD from FreeCAD import Units import FreeCADGui -import PathUtils import Path import Part import PathScripts from PySide import QtCore, QtGui import PathScripts.PathLog as PathLog +import PathScripts.PathUtils as PathUtils LOG_MODULE = 'PathLoadTool' PathLog.setLevel(PathLog.Level.INFO, LOG_MODULE) @@ -194,7 +194,7 @@ class CommandPathLoadTool: PathLog.track("tool: {} with toolNumber: {}".format(tool, toolNumber)) import PathScripts - import PathUtils + from PathScripts import PathUtils obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", "Default Tool") PathScripts.PathLoadTool.LoadTool(obj) diff --git a/src/Mod/Path/PathScripts/PathPostProcessor.py b/src/Mod/Path/PathScripts/PathPostProcessor.py index 68675f54dc..e706439396 100644 --- a/src/Mod/Path/PathScripts/PathPostProcessor.py +++ b/src/Mod/Path/PathScripts/PathPostProcessor.py @@ -34,13 +34,23 @@ class PostProcessor: @classmethod def load(cls, processor): postname = processor + "_post" - - exec("import %s as current_post" % postname) + namespace = {} + + #can't modify function local scope with exec in python3 + exec("from PathScripts import %s as current_post" % postname, namespace) + current_post = namespace['current_post'] + # make sure the script is reloaded if it was previously loaded # should the script have been imported for the first time above # then the initialization code of the script gets executed twice # resulting in 2 load messages if the script outputs one of those. - exec("reload(%s)" % 'current_post') + try: + # Python 2.7 + exec("reload(%s)" % 'current_post') + except NameError: + # Python 3.4+ + from importlib import reload + exec("reload(%s)" % 'current_post') instance = PostProcessor(current_post) instance.units = None diff --git a/src/Mod/Path/PathScripts/PathSelection.py b/src/Mod/Path/PathScripts/PathSelection.py index f5c5d34d4f..9ec2abbbe4 100644 --- a/src/Mod/Path/PathScripts/PathSelection.py +++ b/src/Mod/Path/PathScripts/PathSelection.py @@ -25,7 +25,7 @@ import FreeCAD import FreeCADGui -import PathUtils +import PathScripts.PathUtils as PathUtils import PathScripts.PathLog as PathLog LOG_MODULE = 'PathSelection' diff --git a/src/Mod/Path/PathScripts/PathToolLibraryManager.py b/src/Mod/Path/PathScripts/PathToolLibraryManager.py index b2907e3206..87d0f73303 100644 --- a/src/Mod/Path/PathScripts/PathToolLibraryManager.py +++ b/src/Mod/Path/PathScripts/PathToolLibraryManager.py @@ -30,7 +30,7 @@ import Path import os from PySide import QtCore, QtGui import PathScripts -import PathUtils +from PathScripts import PathUtils import PathScripts.PathLog as PathLog diff --git a/src/Mod/Path/PathScripts/PathUtils.py b/src/Mod/Path/PathScripts/PathUtils.py index c430d0286a..63ede507ec 100644 --- a/src/Mod/Path/PathScripts/PathUtils.py +++ b/src/Mod/Path/PathScripts/PathUtils.py @@ -30,7 +30,7 @@ from DraftGeomUtils import geomType import PathScripts from PathScripts import PathJob import numpy -import PathLog +from PathScripts import PathLog from FreeCAD import Vector import Path from PySide import QtCore