diff options
-rw-r--r-- | coin_build_instructions.py | 4 | ||||
-rw-r--r-- | coin_test_instructions.py | 2 | ||||
-rw-r--r-- | sources/pyside2/cmake/Macros/PySideModules.cmake | 13 | ||||
-rw-r--r-- | sources/pyside2/doc/deployment-pyinstaller.rst | 49 | ||||
-rw-r--r-- | sources/shiboken2/libshiboken/basewrapper.cpp | 99 |
5 files changed, 152 insertions, 15 deletions
diff --git a/coin_build_instructions.py b/coin_build_instructions.py index d094d5b2a..9a7d6272c 100644 --- a/coin_build_instructions.py +++ b/coin_build_instructions.py @@ -101,7 +101,7 @@ def call_setup(python_ver): rmtree(_env, True) run_instruction(["virtualenv", "-p", _pExe, _env], "Failed to create virtualenv") - install_pip_dependencies(env_pip, ["numpy", "setuptools", "sphinx", "six"]) + install_pip_dependencies(env_pip, ["pip", "numpy", "setuptools", "sphinx", "six"]) install_pip_wheel_package(env_pip) cmd = [env_python, "-u", "setup.py"] @@ -116,8 +116,6 @@ def call_setup(python_ver): "--verbose-build"] if python_ver == "3": cmd += ["--limited-api=yes"] - else: - cmd += ["--skip-docs"] # 1.4.2019: errors in sphinx_build on openSUSE 4.2 if is_snapshot_build(): cmd += ["--snapshot-build"] diff --git a/coin_test_instructions.py b/coin_test_instructions.py index 6c3e051bd..e08c257c9 100644 --- a/coin_test_instructions.py +++ b/coin_test_instructions.py @@ -77,7 +77,7 @@ def call_testrunner(python_ver, buildnro): _pExe, _env, env_pip, env_python = get_qtci_virtualEnv(python_ver, CI_HOST_OS, CI_HOST_ARCH, CI_TARGET_ARCH) rmtree(_env, True) run_instruction(["virtualenv", "-p", _pExe, _env], "Failed to create virtualenv") - install_pip_dependencies(env_pip, ["numpy", "PyOpenGL", "setuptools", "six", "pyinstaller"]) + install_pip_dependencies(env_pip, ["pip", "numpy", "PyOpenGL", "setuptools", "six", "pyinstaller"]) install_pip_wheel_package(env_pip) cmd = [env_python, "testrunner.py", "test", "--blacklist", "build_history/blacklist.txt", diff --git a/sources/pyside2/cmake/Macros/PySideModules.cmake b/sources/pyside2/cmake/Macros/PySideModules.cmake index cbf401102..77dc8c8ac 100644 --- a/sources/pyside2/cmake/Macros/PySideModules.cmake +++ b/sources/pyside2/cmake/Macros/PySideModules.cmake @@ -169,6 +169,19 @@ macro(create_pyside_module) set(ld_prefix "LD_LIBRARY_PATH=") endif() set(ld_prefix "${ld_prefix}${pysidebindings_BINARY_DIR}/libpyside${PATH_SEP}${SHIBOKEN_SHARED_LIBRARY_DIR}") + + # On Windows we also need to propagate the whole environment PATH value, because pyside modules + # import Qt, and the Qt modules are found from PATH. + if(WIN32) + # Get the value of PATH with CMake separators. + file(TO_CMAKE_PATH "$ENV{PATH}" path_value) + + # Replace the CMake list separators with "\;"s, to avoid the PATH values being + # interpreted as CMake list elements, we actually want to pass the whole string separated + # by ";" to the command line. + make_path(path_value "${path_value}") + string(APPEND ld_prefix "${PATH_SEP}${path_value}") + endif() set(generate_pyi_options run --skip --sys-path "${pysidebindings_BINARY_DIR}" "${SHIBOKEN_PYTHON_MODULE_DIR}") diff --git a/sources/pyside2/doc/deployment-pyinstaller.rst b/sources/pyside2/doc/deployment-pyinstaller.rst index 8e6a76052..f361daf4a 100644 --- a/sources/pyside2/doc/deployment-pyinstaller.rst +++ b/sources/pyside2/doc/deployment-pyinstaller.rst @@ -122,3 +122,52 @@ an executable inside the `dist/` directory that you can execute:: cd dist/ ./MyApplication + + +Current Caveats To Be Aware Of +============================== + + +PyInstaller Problem +------------------- + +As already mentioned, `PyInstaller` will pick a system installation of PySide2 or +Shiboken2 instead of your virtualenv version without notice, if it exists. +This may be no problem if those PySide2 or shiboken2 versions are the same. + +If you are working with different versions, this can result in frustrating sessions, +when you think you are testing a new version, but `PyInstaller` +is silently working with a different, older version. + + +Problem with numpy in Python 2.7.16 +----------------------------------- + +A recent problem of PyInstaller is the appearance of Python 2.7.16 . +This Python version creates a problem that is known from Python 3 as a `Tcl/Tk` problem. +This does rarely show up in Python 3 because `Tcl/Tk` is seldom used with `PyInstaller. + +On Python 2.7.16, this problem is very much visible, since many people are using numpy. +For some reason, installing `numpy` creates a dependency of `Tcl/Tk`, which can +be circumvented only by explicitly excluding `Tcl/Tk` related things by adding +this line to the analysis section of the spec-file:: + + excludes=['FixTk', 'tcl', 'tk', '_tkinter', 'tkinter', 'Tkinter'], + + +Safety Instructions +------------------- + +o When using `PyInstaller` with `virtualenv`, make sure that there is no system + installation of PySide2 or shiboken2. + +o Before compiling, use `pip -uninstall pyside2 shiboken2 -y` multiple times, until + none of the programs is found anymore. + +o Pip is usually a good tool. But to be 100 % sure, you should directly remove + the PySide2 and shiboken2 folders from site-packages. + +o Be sure to use the right version of pip. The safest way to really run the right + pip, use the Python that you mean: Instead of the pip command, better use:: + + <path/to/your/>python -m pip diff --git a/sources/shiboken2/libshiboken/basewrapper.cpp b/sources/shiboken2/libshiboken/basewrapper.cpp index 6ea793a79..faaca5e4b 100644 --- a/sources/shiboken2/libshiboken/basewrapper.cpp +++ b/sources/shiboken2/libshiboken/basewrapper.cpp @@ -94,6 +94,92 @@ static PyType_Spec SbkObjectType_Type_spec = { }; +#if PY_VERSION_HEX < 0x03000000 +/***************************************************************************** + * + * PYSIDE-816: Workaround for Python 2.7 + * + * This is an add-on for function typeobject.c:tp_new_wrapper from Python 2.7 . + * Problem: + * In Python 3.X, tp_new_wrapper uses this check: + + while (staticbase && (staticbase->tp_new == slot_tp_new)) + + * In Python 2.7, it uses this, instead: + + while (staticbase && (staticbase->tp_flags & Py_TPFLAGS_HEAPTYPE)) + + * The problem is that heap types have this unwanted dependency. + * But we cannot get at static slot_tp_new, and so we have to use + * the original function and patch Py_TPFLAGS_HEAPTYPE away during the call. + */ + +static PyCFunction old_tp_new_wrapper = nullptr; + +static PyObject * +tp_new_wrapper(PyObject *self, PyObject *args, PyObject *kwds) +{ + PyTypeObject *type = reinterpret_cast<PyTypeObject *>(self); + Py_ssize_t orig_flags = type->tp_flags; + type->tp_flags &= ~Py_TPFLAGS_HEAPTYPE; + PyObject *ret = reinterpret_cast<ternaryfunc>(old_tp_new_wrapper)(self, args, kwds); + type->tp_flags = orig_flags; + return ret; +} + +// This is intentionally the new docstring of Python 3.7 . +static struct PyMethodDef tp_new_methoddef[] = { + {"__new__", (PyCFunction)tp_new_wrapper, METH_VARARGS|METH_KEYWORDS, + PyDoc_STR("__new__($type, *args, **kwargs)\n--\n\n" + "Create and return a new object. " + "See help(type) for accurate signature.")}, + {0} +}; + +static int +get_old_tp_new_wrapper(void) +{ + // We get the old tp_new_wrapper from any initialized type. + PyTypeObject *type = &PyType_Type; + PyObject *dict = type->tp_dict; + PyObject *key, *func = nullptr; + Py_ssize_t pos = 0; + while (PyDict_Next(dict, &pos, &key, &func)) { + char *name = PyString_AsString(key); + if (strcmp(name, "__new__") == 0) { + break; + } + } + if (func == nullptr) + return -1; + PyCFunctionObject *pycf_ob = reinterpret_cast<PyCFunctionObject *>(func); + old_tp_new_wrapper = pycf_ob->m_ml->ml_meth; + return 0; +} + +static int +add_tp_new_wrapper(PyTypeObject *type) +{ + // get the original tp_new_wrapper + if (old_tp_new_wrapper == nullptr && get_old_tp_new_wrapper() < 0) + return -1; + // initialize tp_dict + if (type->tp_dict == nullptr) + type->tp_dict = PyDict_New(); + if (type->tp_dict == nullptr) + return -1; + PyObject *ob_type = reinterpret_cast<PyObject *>(type); + Shiboken::AutoDecRef func(PyCFunction_New(tp_new_methoddef, ob_type)); + if (func.isNull()) + return -1; + if (PyDict_SetItemString(type->tp_dict, "__new__", func)) + return -1; + return 0; +} +/*****************************************************************************/ +#endif // PY_VERSION_HEX < 0x03000000 + + PyTypeObject *SbkObjectType_TypeF(void) { static PyTypeObject *type = nullptr; @@ -102,13 +188,8 @@ PyTypeObject *SbkObjectType_TypeF(void) PepHeapType_SIZE + sizeof(SbkObjectTypePrivate); type = reinterpret_cast<PyTypeObject *>(PyType_FromSpec(&SbkObjectType_Type_spec)); #if PY_VERSION_HEX < 0x03000000 - // PYSIDE-816: Python 2.7 has a bad check for Py_TPFLAGS_HEAPTYPE in - // typeobject.c func tp_new_wrapper. In Python 3 it was updated after - // the transition to the new type API, but not in 2.7 . Fortunately, - // the types did not change much when transitioning to heaptypes. We - // pretend that this type is a normal type in 2.7 and hope that this - // has no bad effect. - type->tp_flags &= ~Py_TPFLAGS_HEAPTYPE; + if (add_tp_new_wrapper(type) < 0) + return nullptr; #endif } return type; @@ -299,10 +380,6 @@ void SbkObjectTypeDealloc(PyObject* pyObj) SbkObjectTypePrivate *sotp = PepType_SOTP(pyObj); PyTypeObject *type = reinterpret_cast<PyTypeObject*>(pyObj); -#if PY_VERSION_HEX < 0x03000000 - // PYSIDE-816: Restore the heap type flag. Better safe than sorry. - type->tp_flags |= Py_TPFLAGS_HEAPTYPE; -#endif PyObject_GC_UnTrack(pyObj); #ifndef Py_LIMITED_API Py_TRASHCAN_SAFE_BEGIN(pyObj); |