aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.cpp33
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.h3
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/layout.py25
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/mapping.py44
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/parser.py25
5 files changed, 92 insertions, 38 deletions
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
index c5c0c7c7f..139bc3bb7 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
@@ -729,7 +729,8 @@ void CppGenerator::generateClass(TextStream &s,
if (rfunc->isConstructor()) {
writeConstructorWrapper(s, overloadData, classContext);
- writeSignatureInfo(signatureStream, overloadData);
+ // On constructors, we also generate the property initializers.
+ writeSignatureInfo(signatureStream, overloadData, true);
}
// call operators
else if (rfunc->name() == u"operator()") {
@@ -5284,7 +5285,8 @@ QString CppGenerator::signatureParameter(const AbstractMetaArgument &arg, bool i
return result;
}
-void CppGenerator::writeSignatureInfo(TextStream &s, const OverloadData &overloadData) const
+void CppGenerator::writeSignatureInfo(TextStream &s, const OverloadData &overloadData,
+ bool useProperties) const
{
const auto rfunc = overloadData.referenceFunction();
QString funcName = fullPythonFunctionName(rfunc, false);
@@ -5317,6 +5319,33 @@ void CppGenerator::writeSignatureInfo(TextStream &s, const OverloadData &overloa
args.append(t);
}
}
+ // PYSIDE-1846: In a constructor, provide all properties as keyword-only parameters.
+ const auto &metaClass = rfunc->ownerClass();
+ if (useProperties && !metaClass->propertySpecs().isEmpty()) {
+ args << "*:KeywordOnly=None"_L1;
+ for (const auto &spec : metaClass->propertySpecs()) {
+ auto typeEntry = spec.typeEntry();
+ QString text;
+ if (typeEntry->isFlags()) {
+ const auto fte = std::static_pointer_cast<const FlagsTypeEntry>(typeEntry);
+ text = fte->originator()->qualifiedTargetLangName();
+ } else {
+ text = typeEntry->qualifiedCppName();
+ }
+ auto &inst = spec.type().instantiations();
+ if (!inst.isEmpty()) {
+ text += u'[';
+ for (qsizetype i = 0, size = inst.size(); i < size; ++i) {
+ if (i > 0)
+ text += u", "_s;
+ text += pythonSignature(inst.at(i));
+ }
+ text += u']';
+ }
+ QString entry = spec.name() + u':' + text.replace(u"::"_s, u"."_s) + "=None"_L1;
+ args.append(entry);
+ }
+ }
// mark the multiple signatures as such, to make it easier to generate different code
if (multiple)
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.h b/sources/shiboken6/generator/shiboken/cppgenerator.h
index 387d81ba9..dc4d4a96c 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.h
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.h
@@ -419,7 +419,8 @@ private:
QByteArrayList methodDefinitionParameters(const OverloadData &overloadData) const;
QList<PyMethodDefEntry> methodDefinitionEntries(const OverloadData &overloadData) const;
- void writeSignatureInfo(TextStream &s, const OverloadData &overloads) const;
+ void writeSignatureInfo(TextStream &s, const OverloadData &overloads,
+ bool useProperties=false) const;
QString signatureParameter(const AbstractMetaArgument &arg, bool implicitConversions) const;
QString pythonSignature(const AbstractMetaType &type) const;
/// Writes the implementation of all methods part of python sequence protocol
diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/layout.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/layout.py
index 7d5515c7c..a2d1ca121 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/layout.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/layout.py
@@ -171,12 +171,12 @@ def make_signature_nameless(signature):
signature.parameters[key].__class__ = NamelessParameter
-_POSITIONAL_ONLY = inspect.Parameter.POSITIONAL_ONLY # noqa E:201
+_POSITIONAL_ONLY = inspect.Parameter.POSITIONAL_ONLY # noqa E:201
_POSITIONAL_OR_KEYWORD = inspect.Parameter.POSITIONAL_OR_KEYWORD # noqa E:201
-_VAR_POSITIONAL = inspect.Parameter.VAR_POSITIONAL # noqa E:201
-_KEYWORD_ONLY = inspect.Parameter.KEYWORD_ONLY # noqa E:201
-_VAR_KEYWORD = inspect.Parameter.VAR_KEYWORD # noqa E:201
-_empty = inspect.Parameter.empty # noqa E:201
+_VAR_POSITIONAL = inspect.Parameter.VAR_POSITIONAL # noqa E:201
+_KEYWORD_ONLY = inspect.Parameter.KEYWORD_ONLY # noqa E:201
+_VAR_KEYWORD = inspect.Parameter.VAR_KEYWORD # noqa E:201
+_empty = inspect.Parameter.empty # noqa E:201
default_weights = {
@@ -349,7 +349,13 @@ def create_signature(props, key):
# Build a signature.
kind = DEFAULT_PARAM_KIND
params = []
+
for idx, name in enumerate(varnames):
+ if name == "*":
+ # This is a switch.
+ # Important: It must have a default to simplify the calculation.
+ kind = _KEYWORD_ONLY
+ continue
if name.startswith("**"):
kind = _VAR_KEYWORD
elif name.startswith("*"):
@@ -360,14 +366,19 @@ def create_signature(props, key):
name = name.lstrip("*")
defpos = idx - len(varnames) + len(defaults)
default = defaults[defpos] if defpos >= 0 else _empty
+ if default is not _empty:
+ if kind != _KEYWORD_ONLY:
+ kind = _POSITIONAL_OR_KEYWORD
if default is None:
ann = typing.Optional[ann]
if default is not _empty and layout.ellipsis:
default = ellipsis
+ # See if this is a duplicate name - happens with properties
+ if kind is _KEYWORD_ONLY and varnames.count(name) > 1:
+ continue
param = inspect.Parameter(name, kind, annotation=ann, default=default)
params.append(param)
- if kind == _VAR_POSITIONAL:
- kind = _KEYWORD_ONLY
+
ret_anno = annotations.get('return', _empty)
if ret_anno is not _empty and props["fullname"] in missing_optional_return:
ret_anno = typing.Optional[ret_anno]
diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/mapping.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
index 8e12cc907..f0ef8784d 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
@@ -121,6 +121,10 @@ class Instance(_NotCalled):
pass
+class KeywordOnly(_NotCalled):
+ pass
+
+
# Parameterized primitive variables
class _Parameterized(object):
def __init__(self, type):
@@ -188,6 +192,10 @@ class Reloader(object):
# Modules are in place, we can update the type_map.
g.update(g.pop(proc_name)())
+ # Also record an efficient list of modules for PySide.
+ if mod_name.startswith("PySide6."):
+ pyside_modules.add(mod_name)
+
def check_module(mod):
# During a build, there exist the modules already as directories,
@@ -202,6 +210,7 @@ def check_module(mod):
update_mapping = Reloader().update
type_map = {}
namespace = globals() # our module's __dict__
+pyside_modules: set[str] = set()
type_map.update({
"...": ellipsis,
@@ -298,14 +307,6 @@ type_map.update({
"ushort": int,
"void": int, # be more specific?
"WId": WId,
- "zero(bytes)": b"",
- "zero(Char)": 0,
- "zero(float)": 0,
- "zero(int)": 0,
- "zero(object)": None,
- "zero(str)": "",
- "zero(typing.Any)": None,
- "zero(Any)": None,
# This can be refined by importing numpy.typing optionally, but better than nothing.
"numpy.ndarray": typing.List[typing.Any],
"std.array[int, 4]": typing.List[int],
@@ -387,8 +388,12 @@ type_map.update({
# PYSIDE-1538: We need to treat "std::optional" accordingly.
type_map.update({
"std.optional": typing.Optional,
- })
+})
+# PYSIDE-2846: A special keyord only switching token.
+type_map.update({
+ "KeywordOnly": KeywordOnly("None"),
+})
# The Shiboken Part
def init_Shiboken():
@@ -471,15 +476,9 @@ def init_smart():
# The PySide Part
def init_PySide6_QtCore():
- from PySide6.QtCore import Qt, QUrl, QDir, QKeyCombination, QObject
- from PySide6.QtCore import QRect, QRectF, QSize, QPoint, QLocale, QByteArray
+ from PySide6.QtCore import Qt, QUrl, QDir, QByteArray
+ from PySide6.QtCore import QRect, QRectF, QSize, QPoint
from PySide6.QtCore import QMarginsF # 5.9
- from PySide6.QtCore import SignalInstance
- try:
- # seems to be not generated by 5.9 ATM.
- from PySide6.QtCore import Connection
- except ImportError:
- pass
type_map.update({
"' '": " ",
@@ -506,14 +505,10 @@ def init_PySide6_QtCore():
"PySide6.QtCore.QUrl.ComponentFormattingOptions":
PySide6.QtCore.QUrl.ComponentFormattingOption, # mismatch option/enum, why???
"PyUnicode": typing.Text,
- "QByteArrayView": QByteArray,
+ "QByteArrayView": PySide6.QtCore.QByteArray,
"Q_NULLPTR": None,
"QCalendar.Unspecified": PySide6.QtCore.QCalendar.Unspecified,
"QCborTag(-1)": ulong_max,
- "QDir.Filters(AllEntries | NoDotAndDotDot)": Instance(
- "QDir.Filters(QDir.AllEntries | QDir.NoDotAndDotDot)"),
- "QDir.SortFlags(Name | IgnoreCase)": Instance(
- "QDir.SortFlags(QDir.Name | QDir.IgnoreCase)"),
"QEvent.Type.None": None,
"QGenericArgument((0))": ellipsis, # 5.6, RHEL 6.6. Is that ok?
"QGenericArgument()": ellipsis,
@@ -524,7 +519,7 @@ def init_PySide6_QtCore():
"QJsonObject": typing.Dict[str, PySide6.QtCore.QJsonValue],
"QModelIndex()": Invalid("PySide6.QtCore.QModelIndex"), # repr is btw. very wrong, fix it?!
"QModelIndexList": typing.List[PySide6.QtCore.QModelIndex],
- "PySideSignalInstance": SignalInstance,
+ "PySideSignalInstance": PySide6.QtCore.SignalInstance,
"QString()": "",
"Flag.Default": Instance("PySide6.QtCore.QStringConverterBase.Flags"),
"QStringList()": [],
@@ -537,6 +532,7 @@ def init_PySide6_QtCore():
"QVariant.Type": type, # not so sure here...
"QVariantMap": typing.Dict[str, Variant],
"std.chrono.seconds{5}" : ellipsis,
+ # new entries from property init
})
try:
type_map.update({
@@ -663,9 +659,7 @@ def init_PySide6_QtQuick():
def init_PySide6_QtTest():
- from PySide6.QtCore import SignalInstance
type_map.update({
- "PySideSignalInstance": SignalInstance,
"PySide6.QtTest.QTest.PySideQTouchEventSequence": PySide6.QtTest.QTest.QTouchEventSequence,
"PySide6.QtTest.QTouchEventSequence": PySide6.QtTest.QTest.QTouchEventSequence,
})
diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/parser.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/parser.py
index 490b8a6ec..f54a0a65b 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/parser.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/parser.py
@@ -13,7 +13,7 @@ import warnings
from types import SimpleNamespace
from shibokensupport.signature.mapping import (type_map, update_mapping,
- namespace, _NotCalled, ResultVariable, ArrayLikeVariable) # noqa E:128
+ namespace, _NotCalled, ResultVariable, ArrayLikeVariable, pyside_modules) # noqa E:128
from shibokensupport.signature.lib.tool import build_brace_pattern
_DEBUG = False
@@ -254,10 +254,11 @@ def _resolve_value(thing, valtype, line):
if thing in ("0", "None") and valtype:
if valtype.startswith("PySide6.") or valtype.startswith("typing."):
return None
- map = type_map[valtype]
+ mapped = type_map.get(valtype)
# typing.Any: '_SpecialForm' object has no attribute '__name__'
- name = get_name(map) if hasattr(map, "__name__") else str(map)
+ name = get_name(mapped) if hasattr(mapped, "__name__") else str(mapped)
thing = f"zero({name})"
+ type_map[f"zero({name})"] = None
if thing in type_map:
return type_map[thing]
res = make_good_value(thing, valtype)
@@ -268,6 +269,9 @@ def _resolve_value(thing, valtype, line):
if res is not None:
type_map[thing] = res
return res
+ # Still not found. Look into the imported modules.
+ if res := get_from_another_module(thing):
+ return res
warnings.warn(f"""pyside_type_init:_resolve_value
UNRECOGNIZED: {thing!r}
@@ -323,6 +327,21 @@ def handle_matrix(arg):
return eval(result, globals(), namespace)
+def get_from_another_module(thing):
+ top = thing.split(".", 1)[0] if "." in thing else thing
+ for mod_name in pyside_modules:
+ mod = sys.modules[mod_name]
+ if hasattr(mod, top):
+ try:
+ res = eval(f"{mod_name}.{thing}", globals(), namespace)
+ type_map[thing] = res
+ return res
+ except AttributeError:
+ # Maybe it was anothr module...
+ pass
+ return None
+
+
def _resolve_type(thing, line, level, var_handler, func_name=None):
# manual set of 'str' instead of 'bytes'
if func_name: