aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib')
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/__init__.py40
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py117
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/pyi_generator.py123
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py48
4 files changed, 124 insertions, 204 deletions
diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/__init__.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/__init__.py
index 2d640cb89..e54bec75a 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/__init__.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/__init__.py
@@ -1,40 +1,4 @@
-#############################################################################
-##
-## Copyright (C) 2018 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$
-##
-#############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
# this file intentionally left blank
diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py
index 149881e01..5650e2bc1 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py
@@ -1,41 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2020 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$
-##
-#############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
"""
enum_sig.py
@@ -50,9 +14,7 @@ by producing a lot of clarity.
import inspect
import sys
import types
-import typing
from shibokensupport.signature import get_signature as get_sig
-from shibokensupport.signature.layout import create_signature
"""
@@ -67,6 +29,16 @@ declared in the same class, we use `builtins.property` in the class and
all sub-classes. The same consideration holds for "overload".
"""
+_normal_functions = (types.BuiltinFunctionType, types.FunctionType)
+if hasattr(sys, "pypy_version_info"):
+ # In PyPy, there are more types because our builtin functions
+ # are created differently in C++ and not in PyPy.
+ _normal_functions += (type(get_sig),)
+
+
+def signal_check(thing):
+ return thing and type(thing) in (Signal, SignalInstance)
+
class ExactEnumerator(object):
"""
@@ -78,13 +50,13 @@ class ExactEnumerator(object):
"""
def __init__(self, formatter, result_type=dict):
- global EnumMeta
+ global EnumMeta, Signal, SignalInstance
try:
# Lazy import
- from PySide6.QtCore import Qt
+ from PySide6.QtCore import Qt, Signal, SignalInstance
EnumMeta = type(Qt.Key)
except ImportError:
- EnumMeta = None
+ EnumMeta = Signal = SignalInstance = None
self.fmt = formatter
self.result_type = result_type
@@ -98,7 +70,7 @@ class ExactEnumerator(object):
We check if it is a simple function.
"""
tp = type(self.func)
- return tp not in (types.BuiltinFunctionType, types.FunctionType)
+ return tp not in _normal_functions
def section(self):
if hasattr(self.fmt, "section"):
@@ -126,9 +98,13 @@ class ExactEnumerator(object):
def klass(self, class_name, klass):
ret = self.result_type()
+ if ("._") in class_name:
+ # This happens when introspecting enum.Enum etc. Python 3.8.8 does not
+ # like this, but we want to remove that, anyway.
+ return ret
if "<" in class_name:
# This is happening in QtQuick for some reason:
- ## class QSharedPointer<QQuickItemGrabResult >:
+ # class std::shared_ptr<QQuickItemGrabResult >:
# We simply skip over this class.
return ret
bases_list = []
@@ -146,9 +122,19 @@ class ExactEnumerator(object):
functions = []
enums = []
properties = []
+ signals = []
+ attributes = {}
for thing_name, thing in class_members:
- if inspect.isclass(thing):
+ if signal_check(thing):
+ signals.append((thing_name, thing))
+ elif inspect.isclass(thing):
+ # If this is the only member of the class, it causes the stub
+ # to be printed empty without ..., as self.fmt.have_body will
+ # then be True. (Example: QtCore.QCborTag). Skip it to avoid
+ # this problem.
+ if thing_name == "_member_type_":
+ continue
subclass_name = ".".join((class_name, thing_name))
subclasses.append((subclass_name, thing))
elif inspect.isroutine(thing):
@@ -156,22 +142,32 @@ class ExactEnumerator(object):
functions.append((func_name, thing))
elif type(type(thing)) is EnumMeta:
# take the real enum name, not what is in the dict
- enums.append((thing_name, type(thing).__qualname__, thing))
+ if not thing_name.startswith("_"):
+ enums.append((thing_name, type(thing).__qualname__, thing))
elif isinstance(thing, property):
properties.append((thing_name, thing))
+ # Support attributes that have PySide types as values,
+ # but we skip the 'staticMetaObject' that needs
+ # to be defined at a QObject level.
+ elif "PySide" in str(type(thing)) and "QMetaObject" not in str(type(thing)):
+ if class_name not in attributes:
+ attributes[class_name] = {}
+ attributes[class_name][thing_name] = thing
if thing_name in self.collision_candidates:
self.collision_track.add(thing_name)
init_signature = getattr(klass, "__signature__", None)
- enums.sort(key=lambda tup: tup[1 : 3]) # sort by class then enum value
+ # sort by class then enum value
+ enums.sort(key=lambda tup: (tup[1], tup[2].value))
# We want to handle functions and properties together.
func_prop = sorted(functions + properties, key=lambda tup: tup[0])
# find out how many functions create a signature
- sigs = list(_ for _ in functions if hasattr(_[1], "__signature__") and _[1].__signature__)
- self.fmt.have_body = bool(subclasses or sigs or properties or enums or init_signature)
+ sigs = list(_ for _ in functions if get_sig(_[1]))
+ self.fmt.have_body = bool(subclasses or sigs or properties or enums or # noqa W:504
+ init_signature or signals or attributes)
with self.fmt.klass(class_name, class_str):
self.fmt.level += 1
@@ -181,8 +177,25 @@ class ExactEnumerator(object):
if len(enums):
self.section()
for enum_name, enum_class_name, value in enums:
- with self.fmt.enum(enum_class_name, enum_name, int(value)):
+ with self.fmt.enum(enum_class_name, enum_name, value.value):
pass
+ if hasattr(self.fmt, "signal"):
+ # this is an optional feature
+ if len(signals):
+ self.section()
+ for signal_name, signal in signals:
+ sig_class = type(signal)
+ sig_class_name = f"{sig_class.__qualname__}"
+ sig_str = str(signal)
+ with self.fmt.signal(sig_class_name, signal_name, sig_str):
+ pass
+ if hasattr(self.fmt, "attribute"):
+ if len(attributes):
+ self.section()
+ for class_name, attrs in attributes.items():
+ for attr_name, attr_value in attrs.items():
+ with self.fmt.attribute(attr_name, attr_value):
+ pass
if len(subclasses):
self.section()
for subclass_name, subclass in subclasses:
@@ -206,7 +219,7 @@ class ExactEnumerator(object):
@staticmethod
def get_signature(func):
- return func.__signature__
+ return get_sig(func)
def function(self, func_name, func, decorator=None):
self.func = func # for is_method()
diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/pyi_generator.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/pyi_generator.py
index eb2e49770..ce12dd6c8 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/pyi_generator.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/pyi_generator.py
@@ -1,44 +1,10 @@
LICENSE_TEXT = """
-#############################################################################
-##
-## Copyright (C) 2021 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$
-##
-#############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
"""
+# flake8: noqa E:402
+
"""
pyi_generator.py
@@ -50,7 +16,6 @@ import io
import logging
import os
import re
-import subprocess
import sys
import typing
@@ -58,7 +23,6 @@ from pathlib import Path
from contextlib import contextmanager
from textwrap import dedent
-from shiboken6 import Shiboken
from shibokensupport.signature.lib.enum_sig import HintingEnumerator
from shibokensupport.signature.lib.tool import build_brace_pattern
@@ -96,6 +60,7 @@ class Formatter(Writer):
unrelated tasks of enumeration and formatting apart.
"""
def __init__(self, outfile, options, *args):
+ # XXX Find out which of these patches is still necessary!
self.options = options
Writer.__init__(self, outfile, *args)
# patching __repr__ to disable the __repr__ of typing.TypeVar:
@@ -111,8 +76,12 @@ class Formatter(Writer):
"""
def _typevar__repr__(self):
return f"typing.{self.__name__}"
- typing.TypeVar.__repr__ = _typevar__repr__
-
+ # This is no longer necessary for modern typing versions.
+ # Ignore therefore if the repr is read-only and cannot be changed.
+ try:
+ typing.TypeVar.__repr__ = _typevar__repr__
+ except TypeError:
+ pass
# Adding a pattern to substitute "Union[T, NoneType]" by "Optional[T]"
# I tried hard to replace typing.Optional by a simple override, but
# this became _way_ too much.
@@ -121,6 +90,7 @@ class Formatter(Writer):
pattern = fr"\b Union \s* \[ \s* {brace_pat} \s*, \s* NoneType \s* \]"
replace = r"Optional[\1]"
optional_searcher = re.compile(pattern, flags=re.VERBOSE)
+
def optional_replacer(source):
return optional_searcher.sub(replace, str(source))
self.optional_replacer = optional_replacer
@@ -138,8 +108,6 @@ class Formatter(Writer):
txt = f"""\
# Module `{mod_name}`
- from shiboken6 import Shiboken
-
<<IMPORTS>>
"""
self.print(dedent(txt))
@@ -190,13 +158,17 @@ class Formatter(Writer):
self.print(f"{spaces}{enum_name:25}: {class_name} = ... # {hexval}")
yield
+ @contextmanager
+ def attribute(self, attr_name, attr_value):
+ spaces = indent * self.level
+ self.print(f"{spaces}{attr_name:25} = ... # type: {type(attr_value).__qualname__}")
+ yield
-def get_license_text():
- with sourcepath.open() as f:
- lines = f.readlines()
- license_line = next((lno for lno, line in enumerate(lines)
- if "$QT_END_LICENSE$" in line))
- return "".join(lines[:license_line + 3])
+ @contextmanager
+ def signal(self, class_name, sig_name, sig_str):
+ spaces = indent * self.level
+ self.print(f"{spaces}{sig_name:25}: ClassVar[{class_name}] = ... # {sig_str}")
+ yield
def find_imports(text):
@@ -204,11 +176,16 @@ def find_imports(text):
FROM_IMPORTS = [
- ("typing", "Any Callable Dict List Optional overload Tuple Union".split()),
- ("PySide6.QtCore", ["PyClassProperty"]),
(None, ["builtins"]),
+ (None, ["os"]),
+ (None, ["enum"]),
+ ("collections.abc", ["Iterable"]),
+ ("typing", sorted(typing.__all__)),
+ ("PySide6.QtCore", ["PyClassProperty", "Signal", "SignalInstance"]),
+ ("shiboken6", ["Shiboken"]),
]
+
def filter_from_imports(from_struct, text):
"""
Build a reduced new `from` structure (nfs) with found entries, only
@@ -218,8 +195,15 @@ def filter_from_imports(from_struct, text):
lis = []
nfs.append((mod, lis))
for each in imports:
- if re.search(rf"(\b|@){each}\b", text):
- lis.append(each)
+ # PYSIDE-1603: We search text that is a usage of the class `each`,
+ # but only if the class is not also defined here.
+ if (f"class {each}(") not in text:
+ if re.search(rf"(\b|@){each}\b([^\s\(:]|\n)", text):
+ lis.append(each)
+ # Search if a type is present in the return statement
+ # of function declarations: '... -> here:'
+ if re.search(rf"->.*{each}.*:", text):
+ lis.append(each)
if not lis:
nfs.pop()
return nfs
@@ -258,12 +242,10 @@ def generate_pyi(import_name, outpath, options):
obj = getattr(top, plainname) if import_name != plainname else top
if not getattr(obj, "__file__", None) or Path(obj.__file__).is_dir():
raise ModuleNotFoundError(f"We do not accept a namespace as module `{plainname}`")
- module = sys.modules[import_name]
outfile = io.StringIO()
fmt = Formatter(outfile, options)
fmt.print(LICENSE_TEXT.strip())
- need_imports = options._pyside_call and not USE_PEP563
if USE_PEP563:
fmt.print("from __future__ import annotations")
fmt.print()
@@ -290,6 +272,12 @@ def generate_pyi(import_name, outpath, options):
# we remove the "<<IMPORTS>>" marker and insert imports if needed
if line == "<<IMPORTS>>":
text = outfile.getvalue()
+ wr.print("import " + import_name)
+ for mod_name in find_imports(text):
+ imp = "PySide6." + mod_name
+ if imp != import_name:
+ wr.print("import " + imp)
+ wr.print()
for mod, imports in filter_from_imports(FROM_IMPORTS, text):
import_args = ', '.join(imports)
if mod is None:
@@ -298,27 +286,16 @@ def generate_pyi(import_name, outpath, options):
else:
wr.print(f"from {mod} import {import_args}")
wr.print()
- if need_imports:
- for mod_name in find_imports(text):
- imp = "PySide6." + mod_name
- if imp != import_name:
- wr.print("import " + imp)
- # Do not import Shiboken which is handled already.
- if import_name != "Shiboken":
- wr.print("import " + import_name)
wr.print()
+ wr.print("NoneType: TypeAlias = type[None]")
wr.print()
else:
wr.print(line)
if not options.quiet:
options.logger.info(f"Generated: {outfilepath}")
- if options and (options.check or options.is_ci):
- # Python 3.7 and up: We can check the file directly if the syntax is ok.
- if USE_PEP563:
- subprocess.check_output([sys.executable, os.fspath(outfilepath)])
-if __name__ == "__main__":
+def main():
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
description=dedent("""\
@@ -330,11 +307,10 @@ if __name__ == "__main__":
pyi_generator will try to generate an interface "<module>.pyi".
"""))
parser.add_argument("module",
- help="The full path name of an importable module binary (.pyd, .so)")
+ help="The full path name of an importable module binary (.pyd, .so)") # noqa E:128
parser.add_argument("--quiet", action="store_true", help="Run quietly")
- parser.add_argument("--check", action="store_true", help="Test the output")
parser.add_argument("--outpath",
- help="the output directory (default = location of module binary)")
+ help="the output directory (default = location of module binary)") # noqa E:128
options = parser.parse_args()
module = options.module
outpath = options.outpath
@@ -352,4 +328,7 @@ if __name__ == "__main__":
options.logger = logger
generate_pyi(module, outpath, options=options)
+
+if __name__ == "__main__":
+ main()
# eof
diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py
index 4ded95c36..979dcf4ce 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py
@@ -1,41 +1,5 @@
-#############################################################################
-##
-## 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$
-##
-#############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
"""
tool.py
@@ -80,8 +44,8 @@ def build_brace_pattern(level, separators):
ro, rc = round_ = "()"
so, sc = square = "[]"
- co, cc = curly = "CD" # we insert "{}", later...
- ao, ac = angle = "<>"
+ co, cc = curly = "CD" # noqa E:201 we insert "{}", later...
+ ao, ac = angle = "<>" # noqa E:201
q2, bs, q1 = '"', "\\", "'"
allpat = round_ + square + curly + angle
__ = " "
@@ -115,8 +79,8 @@ def build_brace_pattern(level, separators):
{indent} )*
""")
for idx in range(level):
- pattern = pattern.format(replacer = repeated if idx < level-1 else no_braces_q,
- indent = idx * " ", **locals())
+ pattern = pattern.format(replacer=repeated if idx < level - 1 else no_braces_q,
+ indent=idx * " ", **locals())
return pattern.replace("C", "{").replace("D", "}")