diff options
| -rw-r--r-- | sources/pyside2/PySide2/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | sources/pyside2/PySide2/support/__init__.py | 2 | ||||
| -rw-r--r-- | sources/pyside2/PySide2/support/deprecated.py | 80 | ||||
| -rw-r--r-- | sources/pyside2/tests/QtGui/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | sources/pyside2/tests/QtGui/timed_app_and_patching_test.py (renamed from sources/pyside2/tests/QtGui/timed_app_test.py) | 19 | ||||
| -rw-r--r-- | sources/shiboken2/libshiboken/signature.cpp | 19 | ||||
| -rw-r--r-- | sources/shiboken2/shibokenmodule/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/importhandler.py | 103 | ||||
| -rw-r--r-- | sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py | 12 |
9 files changed, 240 insertions, 3 deletions
diff --git a/sources/pyside2/PySide2/CMakeLists.txt b/sources/pyside2/PySide2/CMakeLists.txt index d666751ea..e39db75a1 100644 --- a/sources/pyside2/PySide2/CMakeLists.txt +++ b/sources/pyside2/PySide2/CMakeLists.txt @@ -37,6 +37,10 @@ endif() configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/__init__.py" "${CMAKE_CURRENT_BINARY_DIR}/support/__init__.py" COPYONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/generate_pyi.py" + "${CMAKE_CURRENT_BINARY_DIR}/support/generate_pyi.py" COPYONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/deprecated.py" + "${CMAKE_CURRENT_BINARY_DIR}/support/deprecated.py" COPYONLY) # now compile all modules. file(READ "${CMAKE_CURRENT_BINARY_DIR}/pyside2_global.h" pyside2_global_contents) diff --git a/sources/pyside2/PySide2/support/__init__.py b/sources/pyside2/PySide2/support/__init__.py index dda01474d..8764fb5cb 100644 --- a/sources/pyside2/PySide2/support/__init__.py +++ b/sources/pyside2/PySide2/support/__init__.py @@ -38,3 +38,5 @@ ############################################################################# from shiboken2 import VoidPtr + +#eof diff --git a/sources/pyside2/PySide2/support/deprecated.py b/sources/pyside2/PySide2/support/deprecated.py new file mode 100644 index 000000000..8538826e4 --- /dev/null +++ b/sources/pyside2/PySide2/support/deprecated.py @@ -0,0 +1,80 @@ +# This Python file uses the following encoding: utf-8 +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +from __future__ import print_function, absolute_import + +""" +deprecated.py + +This module contains deprecated things that are removed from the interface. +They are implemented in Python again, together with a deprecation warning. + +Functions that are to be called for + PySide2.<module> must be named + fix_for_<module> . + +Note that this fixing code is run after all initializations, but before the +import is finished. But that is no problem since the module is passed in. +""" + +import warnings +from textwrap import dedent + + +class PySideDeprecationWarningRemovedInQt6(Warning): + pass + + +def constData(self): + cls = self.__class__ + name = cls.__name__ + warnings.warn(dedent(""" + {name}.constData is unpythonic and will be removed in Qt For Python 6.0 . + Please use {name}.data instead.""" + .format(**locals())), PySideDeprecationWarningRemovedInQt6, stacklevel=2) + return cls.data(self) + + +def fix_for_QtGui(QtGui): + for name, cls in QtGui.__dict__.items(): + if name.startswith("QMatrix") and "data" in cls.__dict__: + cls.constData = constData + +# eof diff --git a/sources/pyside2/tests/QtGui/CMakeLists.txt b/sources/pyside2/tests/QtGui/CMakeLists.txt index 927e72468..172703ab9 100644 --- a/sources/pyside2/tests/QtGui/CMakeLists.txt +++ b/sources/pyside2/tests/QtGui/CMakeLists.txt @@ -46,4 +46,4 @@ PYSIDE_TEST(qtextdocumentwriter_test.py) PYSIDE_TEST(qtextline_test.py) PYSIDE_TEST(qtransform_test.py) PYSIDE_TEST(repr_test.py) -PYSIDE_TEST(timed_app_test.py) +PYSIDE_TEST(timed_app_and_patching_test.py) diff --git a/sources/pyside2/tests/QtGui/timed_app_test.py b/sources/pyside2/tests/QtGui/timed_app_and_patching_test.py index dc0e7c4b0..014aeec1a 100644 --- a/sources/pyside2/tests/QtGui/timed_app_test.py +++ b/sources/pyside2/tests/QtGui/timed_app_and_patching_test.py @@ -29,6 +29,10 @@ import unittest from helper import TimedQApplication +from PySide2.support import deprecated +from PySide2.support.signature import importhandler +from PySide2 import QtGui + class TestTimedApp(TimedQApplication): '''Simple test case for TimedQApplication''' @@ -37,5 +41,20 @@ class TestTimedApp(TimedQApplication): #Simple test of TimedQApplication self.app.exec_() + +def fix_for_QtGui(QtGui): + QtGui.something = 42 + +class TestPatchingFramework(unittest.TestCase): + """Simple test that verifies that deprecated.py works""" + + deprecated.fix_for_QtGui = fix_for_QtGui + + def test_patch_works(self): + something = "something" + self.assertFalse(hasattr(QtGui, something)) + importhandler.finish_import(QtGui) + self.assertTrue(hasattr(QtGui, something)) + if __name__ == '__main__': unittest.main() diff --git a/sources/shiboken2/libshiboken/signature.cpp b/sources/shiboken2/libshiboken/signature.cpp index e62f861a2..7eaf35e1c 100644 --- a/sources/shiboken2/libshiboken/signature.cpp +++ b/sources/shiboken2/libshiboken/signature.cpp @@ -77,6 +77,7 @@ typedef struct safe_globals_struc { PyObject *create_signature_func; PyObject *seterror_argument_func; PyObject *make_helptext_func; + PyObject *finish_import_func; } safe_globals_struc, *safe_globals; static safe_globals pyside_globals = nullptr; @@ -543,6 +544,9 @@ init_phase_1(void) if (p->value_dict == nullptr) goto error; + // This function will be disabled until phase 2 is done. + p->finish_import_func = nullptr; + return p; } error: @@ -585,6 +589,10 @@ init_phase_2(safe_globals_struc *p, PyMethodDef *methods) p->make_helptext_func = PyObject_GetAttrString(loader, "make_helptext"); if (p->make_helptext_func == nullptr) goto error; + p->finish_import_func = PyObject_GetAttrString(loader, "finish_import"); + if (p->finish_import_func == nullptr) + goto error; + return 0; return 0; } error: @@ -1014,7 +1022,16 @@ PySide_FinishSignatures(PyObject *module, const char *signatures[]) return -1; if (_finish_nested_classes(obdict) < 0) return -1; - return 0; + // The finish_import function will not work the first time since phase 2 + // was not yet run. But that is ok, because the first import is always for + // the shiboken module (or a test module). + if (pyside_globals->finish_import_func == nullptr) { + assert(strncmp(name, "PySide2.", 8) != 0); + return 0; + } + Shiboken::AutoDecRef ret(PyObject_CallFunction( + pyside_globals->finish_import_func, const_cast<char *>("(O)"), module)); + return ret.isNull() ? -1 : 0; } static int diff --git a/sources/shiboken2/shibokenmodule/CMakeLists.txt b/sources/shiboken2/shibokenmodule/CMakeLists.txt index 057a995f8..5e5cf21d7 100644 --- a/sources/shiboken2/shibokenmodule/CMakeLists.txt +++ b/sources/shiboken2/shibokenmodule/CMakeLists.txt @@ -53,6 +53,8 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/ "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/layout.py" COPYONLY) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/loader.py" "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/loader.py" COPYONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/importhandler.py" + "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/importhandler.py" COPYONLY) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/mapping.py" "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/mapping.py" COPYONLY) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/parser.py" diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/importhandler.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/importhandler.py new file mode 100644 index 000000000..0417f132a --- /dev/null +++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/importhandler.py @@ -0,0 +1,103 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +from __future__ import print_function, absolute_import + +""" +importhandler.py + +This module handles special actions after the import of PySide modules. +The reason for this was the wish to replace some deprecated functions +by a Python implementation that gives a warning. + +It provides a framework to safely call functions outside of files.dir, +because the implementation of deprecated functions should be visible +to the users (in the hope they don't use it any longer <wink>). + +As a first approach, the function finish_import redirects to +PySide2/support/deprecated.py . There can come other extensions as well. +""" + +try: + from PySide2.support import deprecated + have_deprecated = True +except ImportError: + have_deprecated = False + + +# called by loader.py from signature.cpp +def finish_import(module): + if have_deprecated and module.__name__.startswith("PySide2."): + try: + name = "fix_for_" + module.__name__.split(".")[1] + func = getattr(deprecated, name, None) + if func: + func(module) + except Exception as e: + name = e.__class__.__name__ + print(72 * "*") + print("Error in deprecated.py, ignored:") + print(" {name}: {e}".format(**locals())) + +""" +A note for people who might think this could be written in pure Python: + +Sure, by an explicit import of the modules to patch, this is no problem. +But in the general case, a module should only be imported on user +request and not because we want to patch it. So I started over. + +I then tried to do it on demand by redirection of the __import__ function. +Things worked quite nicely as it seemed, but at second view this solution +was much less appealing. + +Reason: +If someone executes as the first PySide statement + + from PySide2 import QtGui + +then this import is already running. We can see the other imports like the +diverse initializations and QtCore, because it is triggered by import of +QtGui. But the QtGui import can not be seen at all! + +With a lot of effort, sys.setprofile() and stack inspection with the inspect +module, it is *perhaps* possible to solve that. I tried for a day and then +gave up, since the solution is anyway not too nice when __import__ must +be overridden. +""" +#eof diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py index 6c76483a0..3d25c5690 100644 --- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py +++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py @@ -103,6 +103,10 @@ def _typevar__repr__(self): # break the Python license decorated files without an encoding line. # name used in signature.cpp +def pyside_type_init(type_key, sig_strings): + return parser.pyside_type_init(type_key, sig_strings) + +# name used in signature.cpp def create_signature(props, key): return layout.create_signature(props, key) @@ -114,6 +118,11 @@ def seterror_argument(args, func_name): def make_helptext(func): return errorhandler.make_helptext(func) +# name used in signature.cpp +def finish_import(module): + return importhandler.finish_import(module) + + import signature_bootstrap from shibokensupport import signature signature.get_signature = signature_bootstrap.get_signature @@ -194,6 +203,7 @@ def move_into_pyside_package(): put_into_package(PySide2.support.signature, layout) put_into_package(PySide2.support.signature, lib) put_into_package(PySide2.support.signature, parser) + put_into_package(PySide2.support.signature, importhandler) put_into_package(PySide2.support.signature.lib, enum_sig) put_into_package(PySide2.support.signature, typing) @@ -204,8 +214,8 @@ from shibokensupport.signature import errorhandler from shibokensupport.signature import layout from shibokensupport.signature import lib from shibokensupport.signature import parser +from shibokensupport.signature import importhandler from shibokensupport.signature.lib import enum_sig -from shibokensupport.signature.parser import pyside_type_init if "PySide2" in sys.modules: # We publish everything under "PySide2.support.signature", again. |
