From be63fcf734d6fdaf28a83d4f4626f3fe8afa27be Mon Sep 17 00:00:00 2001 From: Christian Tismer Date: Tue, 26 Oct 2021 15:51:05 +0200 Subject: Signature: re-implement error messages for generic types Correct error messages for generic types are a non-trivial problem that was a long-standing FIXME. For typing.Union, typing.Iterable and typing.Sequence this is now implemented. Other generic cases will follow. The problem is the isinstance function which does not work for indexed generic types. It must be implemented by hand, broken up and handled recursively with `any` and `all` expressions. [ChangeLog][PySide6] Error message are more correct now when indexed generic types are involved like Union, Sequence and Iterable. Task-number: PYSIDE-1675 Change-Id: Idb9546bcc9dc02801c19a95f51cdbc8ca5427fbb Reviewed-by: Friedemann Kleint Reviewed-by: Cristian Maureira-Fredes (cherry picked from commit d7357265bed4ab1fff539957df0ec7dbe6b954b2) Reviewed-by: Qt Cherry-pick Bot --- .../shibokensupport/signature/errorhandler.py | 24 ++++++++++++++-------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py index 71f2ffbab..0c1b72644 100644 --- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py +++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py @@ -54,8 +54,10 @@ enough to produce a useful ValueError. This matter will be improved in a later version. """ +import collections.abc import inspect import sys +import typing from shibokensupport.signature import get_signature from shibokensupport.signature.mapping import update_mapping, namespace @@ -64,11 +66,21 @@ from textwrap import dedent def qt_isinstance(inst, the_type): if the_type == float: - return isinstance(inst, int) or isinstance(int, float) + # Qt thinks differently about int and float - simply keep it. + return isinstance(inst, int) or isinstance(inst, float) + if the_type.__module__ == "typing": + if the_type.__origin__ is typing.Union: + return any(qt_isinstance(inst, _) for _ in the_type.__args__) + if the_type.__origin__ in (collections.abc.Sequence, + collections.abc.Iterable): + try: + return all(qt_isinstance(_, the_type.__args__[0]) for _ in inst) + except TypeError: + return False try: return isinstance(inst, the_type) except TypeError as e: - print("FIXME", e) + print(f"FIXME qt_isinstance({inst}, {the_type}):", e) return False @@ -82,13 +94,7 @@ def matched_type(args, sigs): 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: + if all(qt_isinstance(arg, param.annotation) for arg, param in zip(args, params)): return sig return None -- cgit v1.2.3