From a0543241df2273ad60a4c92e4ffe6e0cfb1042b9 Mon Sep 17 00:00:00 2001 From: Christian Tismer Date: Sat, 14 Jul 2018 15:10:56 +0200 Subject: 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 Reviewed-by: Cristian Maureira-Fredes --- sources/shiboken2/shibokenmodule/CMakeLists.txt | 2 + .../support/signature/errorhandler.py | 124 +++++++++++++++++++++ .../shibokenmodule/support/signature/loader.py | 2 + .../shibokenmodule/support/signature/mapping.py | 1 + .../shibokenmodule/support/signature/parser.py | 3 +- 5 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 sources/shiboken2/shibokenmodule/support/signature/errorhandler.py (limited to 'sources/shiboken2/shibokenmodule') 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 -- cgit v1.2.3