aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Tismer <tismer@stackless.com>2019-08-13 11:15:52 +0200
committerChristian Tismer <tismer@stackless.com>2019-08-21 03:30:23 +0200
commit01b43dc3d93e632c3c42fb8e1105f200b9cee2ae (patch)
treef4431f927b267835f940a761ee1bcfb76ac4a580
parent86f56c1ea0846540b082c67d0dc3e942fd311208 (diff)
Add QtCore.Slot.__signature__ and much more manually
The signature of QtCore.Slot and other classes could not automatically be generated because the function is not generated by cppgenerator.cpp . We add it manually in the C++ code into the generation process. The case of QtCore.Slot had diverse follow-up issues to be solved: - Classes which did not inherit from Shiboken were not generated. This is a long-standing omission and creates very many new simple types. - The arity of Slot has default arguments after the varargs parameter "*types". This needed an extended Python parser analysis that fixes the arguments given to the inspect module, accordingly. - The signature generation was completely new implemented and relies no longer on the restricted syntax of a Python (2) function but generates signatures directly as Parameter instances. Implemented classes with hand-made signatures: QtCore.ClassInfo QtCore.MetaFunction, QtCore.MetaSignal QtCore.Property QtCore.Signal QtCore.SignalInstance QtCore.Slot QtQml.ListProperty QtQml.VolatileBool As a side effect, many more subtypes were published. Enums are done, which concludes this work. Fixes: PYSIDE-945 Fixes: PYSIDE-1052 Change-Id: Ic09f02ece3a90325519e42e4e39719beb0c27ae9 Reviewed-by: Christian Tismer <tismer@stackless.com>
-rw-r--r--sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp15
-rw-r--r--sources/pyside2/PySide2/support/generate_pyi.py13
-rw-r--r--sources/pyside2/libpyside/pysideclassinfo.cpp13
-rw-r--r--sources/pyside2/libpyside/pysideclassinfo_p.h2
-rw-r--r--sources/pyside2/libpyside/pysidemetafunction.cpp10
-rw-r--r--sources/pyside2/libpyside/pysideproperty.cpp20
-rw-r--r--sources/pyside2/libpyside/pysidesignal.cpp60
-rw-r--r--sources/pyside2/libpyside/pysideslot.cpp18
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/layout.py38
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py20
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py6
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py14
12 files changed, 164 insertions, 65 deletions
diff --git a/sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp b/sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp
index db297db7c..6427e5198 100644
--- a/sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp
+++ b/sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp
@@ -41,6 +41,7 @@
// shiboken
#include <shiboken.h>
+#include <signature.h>
// pyside
#include <pyside.h>
@@ -469,12 +470,22 @@ PyTypeObject *QtQml_VolatileBoolTypeF(void)
return type;
}
+static const char *PropertyList_SignatureStrings[] = {
+ "PySide2.QtQml.ListProperty(type:type,append:typing.Callable,"
+ "at:typing.Callable=None,clear:typing.Callable=None,count:typing.Callable=None)",
+ nullptr}; // Sentinel
+
+static const char *VolatileBool_SignatureStrings[] = {
+ "PySide2.QtQml.VolatileBool.get()->bool",
+ "PySide2.QtQml.VolatileBool.set(a:object)",
+ nullptr}; // Sentinel
+
void PySide::initQmlSupport(PyObject *module)
{
ElementFactory<PYSIDE_MAX_QML_TYPES - 1>::init();
// Export QmlListProperty type
- if (PyType_Ready(PropertyListTypeF()) < 0) {
+ if (SbkSpecial_Type_Ready(module, PropertyListTypeF(), PropertyList_SignatureStrings) < 0) {
PyErr_Print();
qWarning() << "Error initializing PropertyList type.";
return;
@@ -484,7 +495,7 @@ void PySide::initQmlSupport(PyObject *module)
PyModule_AddObject(module, PepType_GetNameStr(PropertyListTypeF()),
reinterpret_cast<PyObject *>(PropertyListTypeF()));
- if (PyType_Ready(QtQml_VolatileBoolTypeF()) < 0) {
+ if (SbkSpecial_Type_Ready(module, QtQml_VolatileBoolTypeF(), VolatileBool_SignatureStrings) < 0) {
PyErr_Print();
qWarning() << "Error initializing VolatileBool type.";
return;
diff --git a/sources/pyside2/PySide2/support/generate_pyi.py b/sources/pyside2/PySide2/support/generate_pyi.py
index c732227f4..8aa69c983 100644
--- a/sources/pyside2/PySide2/support/generate_pyi.py
+++ b/sources/pyside2/PySide2/support/generate_pyi.py
@@ -141,7 +141,7 @@ class Formatter(Writer):
self.outfile.seek(here)
self.outfile.truncate()
# Note: we cannot use class_str when we have no body.
- self.print("{spaces}class {class_name}: ...".format(**locals()))
+ self.print("{spaces}class {class_str}: ...".format(**locals()))
if "<" in class_name:
# This is happening in QtQuick for some reason:
## class QSharedPointer<QQuickItemGrabResult >:
@@ -168,6 +168,13 @@ class Formatter(Writer):
self.print('{spaces}@staticmethod'.format(**locals()))
self.print('{spaces}def {func_name}{signature}: ...'.format(**locals()))
+ @contextmanager
+ def enum(self, class_name, enum_name, value):
+ spaces = self.spaces
+ hexval = hex(value)
+ self.print("{spaces}{enum_name:20}: {class_name} = ... # {hexval}".format(**locals()))
+ yield
+
def get_license_text():
with io.open(sourcepath) as f:
@@ -247,10 +254,10 @@ def generate_all_pyi(outpath, options):
os.environ["PYTHONPATH"] = pypath
# now we can import
- global PySide2, inspect, HintingEnumerator
+ global PySide2, inspect, HintingEnumerator, EnumType
import PySide2
from PySide2.support.signature import inspect
- from PySide2.support.signature.lib.enum_sig import HintingEnumerator
+ from PySide2.support.signature.lib.enum_sig import HintingEnumerator, EnumType
# propagate USE_PEP563 to the mapping module.
# Perhaps this can be automated?
diff --git a/sources/pyside2/libpyside/pysideclassinfo.cpp b/sources/pyside2/libpyside/pysideclassinfo.cpp
index 288e7f97c..fe5ca8765 100644
--- a/sources/pyside2/libpyside/pysideclassinfo.cpp
+++ b/sources/pyside2/libpyside/pysideclassinfo.cpp
@@ -45,8 +45,7 @@
#include "dynamicqmetaobject.h"
#include <shiboken.h>
-
-#define CLASSINFO_CLASS_NAME "ClassInfo"
+#include <signature.h>
extern "C"
{
@@ -65,7 +64,7 @@ static PyType_Slot PySideClassInfoType_slots[] = {
{0, 0}
};
static PyType_Spec PySideClassInfoType_spec = {
- "PySide2.QtCore." CLASSINFO_CLASS_NAME,
+ "PySide2.QtCore.ClassInfo",
sizeof(PySideClassInfo),
0,
Py_TPFLAGS_DEFAULT,
@@ -179,13 +178,17 @@ void classInfoFree(void *self)
namespace PySide { namespace ClassInfo {
+static const char *ClassInfo_SignatureStrings[] = {
+ "PySide2.QtCore.ClassInfo(**info:typing.Dict[str,str])",
+ nullptr}; // Sentinel
+
void init(PyObject *module)
{
- if (PyType_Ready(PySideClassInfoTypeF()) < 0)
+ if (SbkSpecial_Type_Ready(module, PySideClassInfoTypeF(), ClassInfo_SignatureStrings) < 0)
return;
Py_INCREF(PySideClassInfoTypeF());
- PyModule_AddObject(module, CLASSINFO_CLASS_NAME, reinterpret_cast<PyObject *>(PySideClassInfoTypeF()));
+ PyModule_AddObject(module, "ClassInfo", reinterpret_cast<PyObject *>(PySideClassInfoTypeF()));
}
bool checkType(PyObject *pyObj)
diff --git a/sources/pyside2/libpyside/pysideclassinfo_p.h b/sources/pyside2/libpyside/pysideclassinfo_p.h
index 426aee133..c0038a71a 100644
--- a/sources/pyside2/libpyside/pysideclassinfo_p.h
+++ b/sources/pyside2/libpyside/pysideclassinfo_p.h
@@ -44,7 +44,7 @@
#include <QMetaObject>
#include "pysideclassinfo.h"
-#define __INFO_ATTR_NAME__ "__classInfo__"
+#define __INFO_ATTR_NAME__ "__classInfo__" // not used! ???
struct PySideClassInfo;
diff --git a/sources/pyside2/libpyside/pysidemetafunction.cpp b/sources/pyside2/libpyside/pysidemetafunction.cpp
index 346117201..e0e0c439b 100644
--- a/sources/pyside2/libpyside/pysidemetafunction.cpp
+++ b/sources/pyside2/libpyside/pysidemetafunction.cpp
@@ -41,6 +41,7 @@
#include "pysidemetafunction_p.h"
#include <shiboken.h>
+#include <signature.h>
#include <QtCore/QMetaMethod>
@@ -65,7 +66,7 @@ static PyType_Slot PySideMetaFunctionType_slots[] = {
{0, 0}
};
static PyType_Spec PySideMetaFunctionType_spec = {
- "PySide.MetaFunction",
+ "PySide2.QtCore.MetaFunction",
sizeof(PySideMetaFunction),
0,
Py_TPFLAGS_DEFAULT,
@@ -101,11 +102,16 @@ PyObject *functionCall(PyObject *self, PyObject *args, PyObject * /* kw */)
namespace PySide { namespace MetaFunction {
+static const char *MetaFunction_SignatureStrings[] = {
+ "PySide2.QtCore.MetaFunction.__call__(*args:typing.Any)->typing.Any",
+ nullptr}; // Sentinel
+
void init(PyObject *module)
{
- if (PyType_Ready(PySideMetaFunctionTypeF()) < 0)
+ if (SbkSpecial_Type_Ready(module, PySideMetaFunctionTypeF(), MetaFunction_SignatureStrings) < 0)
return;
+ Py_INCREF(PySideMetaFunctionTypeF());
PyModule_AddObject(module, "MetaFunction", reinterpret_cast<PyObject *>(PySideMetaFunctionTypeF()));
}
diff --git a/sources/pyside2/libpyside/pysideproperty.cpp b/sources/pyside2/libpyside/pysideproperty.cpp
index a9cacf869..d9d15eb3b 100644
--- a/sources/pyside2/libpyside/pysideproperty.cpp
+++ b/sources/pyside2/libpyside/pysideproperty.cpp
@@ -45,8 +45,7 @@
#include "pysidesignal_p.h"
#include <shiboken.h>
-
-#define QPROPERTY_CLASS_NAME "Property"
+#include <signature.h>
extern "C"
{
@@ -82,7 +81,7 @@ static PyType_Slot PySidePropertyType_slots[] = {
};
// Dotted modulename is crucial for PyType_FromSpec to work. Is this name right?
static PyType_Spec PySidePropertyType_spec = {
- "PySide2.QtCore." QPROPERTY_CLASS_NAME,
+ "PySide2.QtCore.Property",
sizeof(PySideProperty),
0,
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_BASETYPE,
@@ -321,13 +320,24 @@ static PyObject *getFromType(PyTypeObject *type, PyObject *name)
namespace PySide { namespace Property {
+static const char *Property_SignatureStrings[] = {
+ "PySide2.QtCore.Property(type:type,fget:typing.Callable=None,fset:typing.Callable=None,"
+ "freset:typing.Callable=None,fdel:typing.Callable=None,doc:str=None,"
+ "notify:typing.Callable=None,designable:bool=True,scriptable:bool=True,"
+ "stored:bool=True,user:bool=False,constant:bool=False,final:bool=False)",
+ "PySide2.QtCore.Property.getter(func:typing.Callable)",
+ "PySide2.QtCore.Property.read(func:typing.Callable)",
+ "PySide2.QtCore.Property.setter(func:typing.Callable)",
+ "PySide2.QtCore.Property.write(func:typing.Callable)",
+ nullptr}; // Sentinel
+
void init(PyObject *module)
{
- if (PyType_Ready(PySidePropertyTypeF()) < 0)
+ if (SbkSpecial_Type_Ready(module, PySidePropertyTypeF(), Property_SignatureStrings) < 0)
return;
Py_INCREF(PySidePropertyTypeF());
- PyModule_AddObject(module, QPROPERTY_CLASS_NAME, reinterpret_cast<PyObject *>(PySidePropertyTypeF()));
+ PyModule_AddObject(module, "Property", reinterpret_cast<PyObject *>(PySidePropertyTypeF()));
}
bool checkType(PyObject *pyObj)
diff --git a/sources/pyside2/libpyside/pysidesignal.cpp b/sources/pyside2/libpyside/pysidesignal.cpp
index 434ef6ac3..a09c17a24 100644
--- a/sources/pyside2/libpyside/pysidesignal.cpp
+++ b/sources/pyside2/libpyside/pysidesignal.cpp
@@ -47,12 +47,11 @@
#include <QtCore/QObject>
#include <QtCore/QMetaMethod>
#include <QtCore/QMetaObject>
+#include <signature.h>
#include <algorithm>
#include <utility>
-#define SIGNAL_CLASS_NAME "Signal"
-#define SIGNAL_INSTANCE_NAME "SignalInstance"
#define QT_SIGNAL_SENTINEL '2'
namespace PySide {
@@ -101,35 +100,35 @@ static PyObject *signalCall(PyObject *, PyObject *, PyObject *);
static PyObject *metaSignalCheck(PyObject *, PyObject *);
-static PyMethodDef Signal_methods[] = {
- {"__instancecheck__", (PyCFunction)metaSignalCheck, METH_O, NULL},
+static PyMethodDef MetaSignal_methods[] = {
+ {"__instancecheck__", (PyCFunction)metaSignalCheck, METH_O|METH_STATIC, NULL},
{0, 0, 0, 0}
};
-static PyType_Slot PySideSignalMetaType_slots[] = {
- {Py_tp_methods, (void *)Signal_methods},
+static PyType_Slot PySideMetaSignalType_slots[] = {
+ {Py_tp_methods, (void *)MetaSignal_methods},
{Py_tp_base, (void *)&PyType_Type},
{Py_tp_free, (void *)PyObject_GC_Del},
{Py_tp_dealloc, (void *)object_dealloc},
{0, 0}
};
-static PyType_Spec PySideSignalMetaType_spec = {
+static PyType_Spec PySideMetaSignalType_spec = {
"PySide2.QtCore.MetaSignal",
0,
// sizeof(PyHeapTypeObject) is filled in by PyType_FromSpecWithBases
// which calls PyType_Ready which calls inherit_special.
0,
Py_TPFLAGS_DEFAULT,
- PySideSignalMetaType_slots,
+ PySideMetaSignalType_slots,
};
-PyTypeObject *PySideSignalMetaTypeF(void)
+PyTypeObject *PySideMetaSignalTypeF(void)
{
static PyTypeObject *type = nullptr;
if (!type) {
PyObject *bases = Py_BuildValue("(O)", &PyType_Type);
- type = (PyTypeObject *)PyType_FromSpecWithBases(&PySideSignalMetaType_spec, bases);
+ type = (PyTypeObject *)PyType_FromSpecWithBases(&PySideMetaSignalType_spec, bases);
Py_XDECREF(bases);
}
return type;
@@ -146,7 +145,7 @@ static PyType_Slot PySideSignalType_slots[] = {
{0, 0}
};
static PyType_Spec PySideSignalType_spec = {
- "PySide2.QtCore." SIGNAL_CLASS_NAME,
+ "PySide2.QtCore.Signal",
sizeof(PySideSignal),
0,
Py_TPFLAGS_DEFAULT,
@@ -160,7 +159,7 @@ PyTypeObject *PySideSignalTypeF(void)
if (!type) {
type = (PyTypeObject *)PyType_FromSpec(&PySideSignalType_spec);
PyTypeObject *hold = Py_TYPE(type);
- Py_TYPE(type) = PySideSignalMetaTypeF();
+ Py_TYPE(type) = PySideMetaSignalTypeF();
Py_INCREF(Py_TYPE(type));
Py_DECREF(hold);
}
@@ -185,7 +184,7 @@ static PyType_Slot PySideSignalInstanceType_slots[] = {
{0, 0}
};
static PyType_Spec PySideSignalInstanceType_spec = {
- "PySide2.QtCore." SIGNAL_INSTANCE_NAME,
+ "PySide2.QtCore.SignalInstance",
sizeof(PySideSignalInstance),
0,
Py_TPFLAGS_DEFAULT,
@@ -211,7 +210,7 @@ int signalTpInit(PyObject *self, PyObject *args, PyObject *kwds)
emptyTuple = PyTuple_New(0);
if (!PyArg_ParseTupleAndKeywords(emptyTuple, kwds,
- "|sO:QtCore." SIGNAL_CLASS_NAME, const_cast<char **>(kwlist), &argName, &argArguments))
+ "|sO:QtCore.Signal", const_cast<char **>(kwlist), &argName, &argArguments))
return -1;
bool tupledArgs = false;
@@ -317,7 +316,7 @@ PyObject *signalInstanceConnect(PyObject *self, PyObject *args, PyObject *kwds)
static const char *kwlist[] = {"slot", "type", nullptr};
if (!PyArg_ParseTupleAndKeywords(args, kwds,
- "O|O:" SIGNAL_INSTANCE_NAME, const_cast<char **>(kwlist), &slot, &type))
+ "O|O:SignalInstance", const_cast<char **>(kwlist), &slot, &type))
return 0;
PySideSignalInstance *source = reinterpret_cast<PySideSignalInstance *>(self);
@@ -585,9 +584,9 @@ PyObject *signalInstanceCall(PyObject *self, PyObject *args, PyObject *kw)
return PyCFunction_Call(homonymousMethod, args, kw);
}
-static PyObject *metaSignalCheck(PyObject * /* klass */, PyObject *args)
+static PyObject *metaSignalCheck(PyObject * /* klass */, PyObject *arg)
{
- if (PyType_IsSubtype(Py_TYPE(args), PySideSignalInstanceTypeF()))
+ if (PyType_IsSubtype(Py_TYPE(arg), PySideSignalInstanceTypeF()))
Py_RETURN_TRUE;
else
Py_RETURN_FALSE;
@@ -598,21 +597,36 @@ static PyObject *metaSignalCheck(PyObject * /* klass */, PyObject *args)
namespace PySide {
namespace Signal {
+static const char *MetaSignal_SignatureStrings[] = {
+ "PySide2.QtCore.MetaSignal.__instancecheck__(object:object)->bool",
+ nullptr}; // Sentinel
+
+static const char *Signal_SignatureStrings[] = {
+ "PySide2.QtCore.Signal(*types:type,name:str=nullptr,arguments:str=nullptr)",
+ nullptr}; // Sentinel
+
+static const char *SignalInstance_SignatureStrings[] = {
+ "PySide2.QtCore.SignalInstance.connect(slot:object,type:type=nullptr)",
+ "PySide2.QtCore.SignalInstance.disconnect(slot:object=nullptr)",
+ "PySide2.QtCore.SignalInstance.emit(*args:typing.Any)",
+ nullptr}; // Sentinel
+
void init(PyObject *module)
{
- if (PyType_Ready(PySideSignalMetaTypeF()) < 0)
+ if (SbkSpecial_Type_Ready(module, PySideMetaSignalTypeF(), MetaSignal_SignatureStrings) < 0)
return;
+ Py_INCREF(PySideSignalTypeF());
+ PyModule_AddObject(module, "MetaSignal", reinterpret_cast<PyObject *>(PySideMetaSignalTypeF()));
- if (PyType_Ready(PySideSignalTypeF()) < 0)
+ if (SbkSpecial_Type_Ready(module, PySideSignalTypeF(), Signal_SignatureStrings) < 0)
return;
-
Py_INCREF(PySideSignalTypeF());
- PyModule_AddObject(module, SIGNAL_CLASS_NAME, reinterpret_cast<PyObject *>(PySideSignalTypeF()));
+ PyModule_AddObject(module, "Signal", reinterpret_cast<PyObject *>(PySideSignalTypeF()));
- if (PyType_Ready(PySideSignalInstanceTypeF()) < 0)
+ if (SbkSpecial_Type_Ready(module, PySideSignalInstanceTypeF(), SignalInstance_SignatureStrings) < 0)
return;
-
Py_INCREF(PySideSignalInstanceTypeF());
+ PyModule_AddObject(module, "SignalInstance", reinterpret_cast<PyObject *>(PySideSignalInstanceTypeF()));
}
bool checkType(PyObject *pyObj)
diff --git a/sources/pyside2/libpyside/pysideslot.cpp b/sources/pyside2/libpyside/pysideslot.cpp
index 2f8e69e8f..204253aa2 100644
--- a/sources/pyside2/libpyside/pysideslot.cpp
+++ b/sources/pyside2/libpyside/pysideslot.cpp
@@ -45,8 +45,7 @@
#include <QtCore/QMetaObject>
#include <QtCore/QString>
-
-#define SLOT_DEC_NAME "Slot"
+#include <signature.h>
struct SlotData
{
@@ -76,7 +75,7 @@ static PyType_Slot PySideSlotType_slots[] = {
{0, 0}
};
static PyType_Spec PySideSlotType_spec = {
- "PySide2.QtCore." SLOT_DEC_NAME,
+ "PySide2.QtCore.Slot",
sizeof(PySideSlot),
0,
Py_TPFLAGS_DEFAULT,
@@ -102,7 +101,7 @@ int slotTpInit(PyObject *self, PyObject *args, PyObject *kw)
if (emptyTuple == 0)
emptyTuple = PyTuple_New(0);
- if (!PyArg_ParseTupleAndKeywords(emptyTuple, kw, "|sO:QtCore." SLOT_DEC_NAME,
+ if (!PyArg_ParseTupleAndKeywords(emptyTuple, kw, "|sO:QtCore.Slot",
const_cast<char **>(kwlist), &argName, &argResult)) {
return -1;
}
@@ -177,15 +176,20 @@ PyObject *slotCall(PyObject *self, PyObject *args, PyObject * /* kw */)
} // extern "C"
-namespace PySide { namespace Slot {
+namespace PySide {
+namespace Slot {
+
+static const char *Slot_SignatureStrings[] = {
+ "PySide2.QtCore.Slot(*types:type,name:str=nullptr,result:str=nullptr)->typing.Callable[...,typing.Optional[str]]",
+ nullptr}; // Sentinel
void init(PyObject *module)
{
- if (PyType_Ready(PySideSlotTypeF()) < 0)
+ if (SbkSpecial_Type_Ready(module, PySideSlotTypeF(), Slot_SignatureStrings) < 0)
return;
Py_INCREF(PySideSlotTypeF());
- PyModule_AddObject(module, SLOT_DEC_NAME, reinterpret_cast<PyObject *>(PySideSlotTypeF()));
+ PyModule_AddObject(module, "Slot", reinterpret_cast<PyObject *>(PySideSlotTypeF()));
}
} // namespace Slot
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/layout.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/layout.py
index bd827f1ee..af8ada065 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/layout.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/layout.py
@@ -174,6 +174,13 @@ def make_signature_nameless(signature):
signature.parameters[key].__class__ = NamelessParameter
+_POSITIONAL_ONLY = inspect._POSITIONAL_ONLY
+_POSITIONAL_OR_KEYWORD = inspect._POSITIONAL_OR_KEYWORD
+_VAR_POSITIONAL = inspect._VAR_POSITIONAL
+_KEYWORD_ONLY = inspect._KEYWORD_ONLY
+_VAR_KEYWORD = inspect._VAR_KEYWORD
+_empty = inspect._empty
+
def create_signature(props, key):
if not props:
# empty signatures string
@@ -204,8 +211,8 @@ def create_signature(props, key):
elif sig_kind == "classmethod":
varnames = ("klass",) + varnames
else:
- raise SystemError("Methods must be function, method, staticmethod or "
- "classmethod")
+ raise SystemError("Methods must be function, method, staticmethod"
+ " or classmethod")
# calculate the modifications
defaults = props["defaults"][:]
if not layout.defaults:
@@ -216,14 +223,25 @@ def create_signature(props, key):
if not layout.return_annotation and "return" in annotations:
del annotations["return"]
- # attach parameters to a fake function and build a signature
- argstr = ", ".join(varnames)
- fakefunc = eval("lambda {}: None".format(argstr))
- fakefunc.__name__ = props["name"]
- fakefunc.__defaults__ = defaults
- fakefunc.__kwdefaults__ = props["kwdefaults"]
- fakefunc.__annotations__ = annotations
- sig = inspect._signature_from_function(inspect.Signature, fakefunc)
+ # Build a signature.
+ kind = inspect._POSITIONAL_OR_KEYWORD
+ params = []
+ for idx, name in enumerate(varnames):
+ if name.startswith("**"):
+ kind = _VAR_KEYWORD
+ elif name.startswith("*"):
+ kind = _VAR_POSITIONAL
+ ann = annotations.get(name, _empty)
+ name = name.lstrip("*")
+ defpos = idx - len(varnames) + len(defaults)
+ default = defaults[defpos] if defpos >= 0 else _empty
+ param = inspect.Parameter(name, kind, annotation=ann, default=default)
+ params.append(param)
+ if kind == _VAR_POSITIONAL:
+ kind = _KEYWORD_ONLY
+ sig = inspect.Signature(params,
+ return_annotation=annotations.get('return', _empty),
+ __validate_parameters__=False)
# the special case of nameless parameters
if not layout.parameter_names:
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py
index e6f6dc379..42b123046 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py
@@ -52,6 +52,11 @@ by producing a lot of clarity.
import sys
from shibokensupport.signature import inspect
from shibokensupport.signature import get_signature
+try:
+ from PySide2.QtCore import Qt
+ EnumType = type(Qt.Key)
+except ImportError:
+ EnumType = None
class ExactEnumerator(object):
@@ -82,7 +87,8 @@ class ExactEnumerator(object):
return ret
def klass(self, class_name, klass):
- if not "Shiboken" in repr(klass.mro()):
+ modname = klass.__module__
+ if not (modname.startswith("PySide2") or modname.startswith("shiboken2")):
# don't look into any foreign classes!
ret = self.result_type()
return ret
@@ -111,6 +117,8 @@ class ExactEnumerator(object):
ret.update(self.function(func_name, thing))
for subclass_name, subclass in subclasses:
ret.update(self.klass(subclass_name, subclass))
+ if isinstance(subclass, EnumType):
+ self.enum(subclass)
return ret
def function(self, func_name, func):
@@ -121,6 +129,16 @@ class ExactEnumerator(object):
ret[key] = signature
return ret
+ def enum(self, subclass):
+ if not hasattr(self.fmt, "enum"):
+ # this is an optional feature
+ return
+ class_name = subclass.__name__
+ for enum_name, value in subclass.__dict__.items():
+ if type(type(value)) is EnumType:
+ with self.fmt.enum(class_name, enum_name, int(value)):
+ pass
+
def stringify(signature):
if isinstance(signature, list):
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
index 36b137104..10d0f16ad 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
@@ -67,6 +67,10 @@ ModelIndexList = typing.List[int]
QImageCleanupFunction = typing.Callable
StringList = typing.List[str]
+# unfortunately, typing.Optional[t] expands to typing.Union[t, NoneType]
+# Until we can force it to create Optional[t] again, we use this.
+NoneType = type(None)
+
_S = TypeVar("_S")
# Building our own Char type, which is much nicer than
@@ -316,6 +320,7 @@ type_map.update({
"zero(int)": 0,
"zero(object)": None,
"zero(str)": "",
+ "...": "...",
})
@@ -345,6 +350,7 @@ def init_sample():
"Foo.HANDLE": int,
"HANDLE": int,
"Null": None,
+ "nullptr": None,
"ObjectType.Identifier": Missing("sample.ObjectType.Identifier"),
"OddBool": bool,
"PStr": str,
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
index 6109bceee..3d14ec7b3 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
@@ -116,7 +116,7 @@ def _parse_line(line):
print("KEYWORD", ret)
name = name + "_"
if "=" in ann:
- ann, default = ann.split("=")
+ ann, default = ann.split("=", 1)
tup = name, ann, default
else:
tup = name, ann
@@ -167,9 +167,11 @@ def try_to_guess(thing, valtype):
def _resolve_value(thing, valtype, line):
if thing in ("0", "None") and valtype:
- if valtype.startswith("PySide2."):
+ if valtype.startswith("PySide2.") or valtype.startswith("typing."):
return None
- name = type_map[valtype].__name__
+ mapped = type_map[valtype]
+ # typing.Any: '_SpecialForm' object has no attribute '__name__'
+ name = mapped.__name__ if hasattr(mapped, "__name__") else str(mapped)
thing = "zero({})".format(name)
if thing in type_map:
return type_map[thing]
@@ -275,9 +277,9 @@ def calculate_props(line):
for idx, tup in enumerate(arglist):
name, ann = tup[:2]
if ann == "...":
- name = "*args"
- # copy the fields back :()
- ann = 'NULL' # maps to None
+ name = "*args" if name.startswith("arg_") else "*" + name
+ # copy the pathed fields back
+ ann = 'nullptr' # maps to None
tup = name, ann
arglist[idx] = tup
annotations[name] = _resolve_type(ann, line, 0)