diff options
author | Christian Tismer <tismer@stackless.com> | 2018-07-14 15:10:56 +0200 |
---|---|---|
committer | Christian Tismer <tismer@stackless.com> | 2019-01-10 09:15:44 +0000 |
commit | a0543241df2273ad60a4c92e4ffe6e0cfb1042b9 (patch) | |
tree | 0e12bac1f772c6f8a985c63709e89231c3889e56 /sources/shiboken2/shibokenmodule | |
parent | 77265fcedc3411fb70e149cf9d9cd4f549de80e6 (diff) |
Produce TypeError Messages Using the Signature Module
The TypeError messages can now be produced, based upon the
signature module.
As a feature under test, we produce ValueErrors instead in
certain cases. This will probably improve, later.
We are currently investigating how much can be determined,
automatically.
Task-number: PYSIDE-795
Change-Id: Ie8a648beaf8a3bed388e3c01ba501bb36859722e
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'sources/shiboken2/shibokenmodule')
5 files changed, 130 insertions, 2 deletions
diff --git a/sources/shiboken2/shibokenmodule/CMakeLists.txt b/sources/shiboken2/shibokenmodule/CMakeLists.txt index 0eba3eaff..373ce102f 100644 --- a/sources/shiboken2/shibokenmodule/CMakeLists.txt +++ b/sources/shiboken2/shibokenmodule/CMakeLists.txt @@ -57,6 +57,8 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/__init__.py" "${CMAKE_CURRENT_BINARY_DIR}/support/__init__.py" COPYONLY) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/__init__.py" "${CMAKE_CURRENT_BINARY_DIR}/support/signature/__init__.py" COPYONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/errorhandler.py" + "${CMAKE_CURRENT_BINARY_DIR}/support/signature/errorhandler.py" COPYONLY) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/layout.py" "${CMAKE_CURRENT_BINARY_DIR}/support/signature/layout.py" COPYONLY) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/loader.py" diff --git a/sources/shiboken2/shibokenmodule/support/signature/errorhandler.py b/sources/shiboken2/shibokenmodule/support/signature/errorhandler.py new file mode 100644 index 000000000..902bb05af --- /dev/null +++ b/sources/shiboken2/shibokenmodule/support/signature/errorhandler.py @@ -0,0 +1,124 @@ +############################################################################# +## +## 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 + +""" +errorhandler.py + +This module handles the TypeError messages which were previously +produced by the generated C code. + +This version is at least consistent with the signatures, which +are created by the same module. + +Experimentally, we are trying to guess those errors which are +just the wrong number of elements in an iterator. +At the moment, it is unclear whether the information given is +enough to produce a useful ValueError. + +This matter will be improved in a later version. +""" + +from signature_loader import get_signature, inspect +from signature_loader.mapping import update_mapping, namespace +from textwrap import dedent + + +def qt_isinstance(inst, the_type): + if the_type == float: + return isinstance(inst, int) or isinstance(int, float) + try: + return isinstance(inst, the_type) + except TypeError as e: + print("FIXME", e) + return False + + +def matched_type(args, sigs): + for sig in sigs: + params = list(sig.parameters.values()) + if len(args) > len(params): + continue + if len(args) < len(params): + k = len(args) + if params[k].default is params[k].empty: + # this is a necessary parameter, so it fails. + continue + ok = True + for arg, param in zip(args, params): + ann = param.annotation + if qt_isinstance(arg, ann): + continue + ok = False + if ok: + return sig + return None + + +def seterror_argument(args, func_name): + update_mapping() + func = eval(func_name, namespace) + sigs = get_signature(func, "typeerror") + if type(sigs) != list: + sigs = [sigs] + if type(args) != tuple: + args = (args,) + # temp! + found = matched_type(args, sigs) + if found: + msg = dedent(""" + '{func_name}' called with wrong argument values: + {func_name}{args} + Found signature: + {func_name}{found} + """.format(**locals())).strip() + return ValueError, msg + type_str = ", ".join(type(arg).__name__ for arg in args) + msg = dedent(""" + '{func_name}' called with wrong argument types: + {func_name}({type_str}) + Supported signatures: + """.format(**locals())).strip() + for sig in sigs: + msg += "\n {func_name}{sig}".format(**locals()) + # We don't raise the error here, to avoid the loader in the traceback. + return TypeError, msg + +# end of file diff --git a/sources/shiboken2/shibokenmodule/support/signature/loader.py b/sources/shiboken2/shibokenmodule/support/signature/loader.py index de27d441c..be30483fe 100644 --- a/sources/shiboken2/shibokenmodule/support/signature/loader.py +++ b/sources/shiboken2/shibokenmodule/support/signature/loader.py @@ -181,6 +181,8 @@ with ensure_import_support(): mapping = sbk_mapping mapping.__name__ = "mapping" put_into_loader_package(mapping) + from support.signature import errorhandler + put_into_loader_package(errorhandler) from support.signature import layout put_into_loader_package(layout) from support.signature.lib import enum_sig diff --git a/sources/shiboken2/shibokenmodule/support/signature/mapping.py b/sources/shiboken2/shibokenmodule/support/signature/mapping.py index 0195f0280..40db43729 100644 --- a/sources/shiboken2/shibokenmodule/support/signature/mapping.py +++ b/sources/shiboken2/shibokenmodule/support/signature/mapping.py @@ -203,6 +203,7 @@ def check_module(mod): update_mapping = Reloader().update type_map = {} +namespace = globals() # our module's __dict__ def init_Shiboken(): diff --git a/sources/shiboken2/shibokenmodule/support/signature/parser.py b/sources/shiboken2/shibokenmodule/support/signature/parser.py index 5178d9ef9..2f6e6e3f5 100644 --- a/sources/shiboken2/shibokenmodule/support/signature/parser.py +++ b/sources/shiboken2/shibokenmodule/support/signature/parser.py @@ -45,8 +45,7 @@ import warnings import types import keyword import functools -from signature_loader.mapping import ( - type_map, update_mapping, __dict__ as namespace) +from signature_loader.mapping import type_map, update_mapping, namespace _DEBUG = False LIST_KEYWORDS = False |