diff options
7 files changed, 74 insertions, 66 deletions
diff --git a/sources/pyside2/PySide2/support/generate_pyi.py b/sources/pyside2/PySide2/support/generate_pyi.py index d5bbe5d7c..e60645701 100644 --- a/sources/pyside2/PySide2/support/generate_pyi.py +++ b/sources/pyside2/PySide2/support/generate_pyi.py @@ -161,14 +161,11 @@ class Formatter(Writer): if self.level == 0: self.print() here = self.outfile.tell() - self.print("{spaces}class {class_str}:".format(**locals())) - pos = self.outfile.tell() - yield - if pos == self.outfile.tell(): - # we have not written any function - self.outfile.seek(here) - self.outfile.truncate() + if self.have_body: + self.print("{spaces}class {class_str}:".format(**locals())) + else: self.print("{spaces}class {class_str}: ...".format(**locals())) + yield if "<" in class_name: # This is happening in QtQuick for some reason: ## class QSharedPointer<QQuickItemGrabResult >: diff --git a/sources/pyside2/tests/registry/existence_test.py b/sources/pyside2/tests/registry/existence_test.py index fd81901b4..f5f614d04 100644 --- a/sources/pyside2/tests/registry/existence_test.py +++ b/sources/pyside2/tests/registry/existence_test.py @@ -103,8 +103,10 @@ except SyntaxError: print("*** not a python file, removed:", shortpath) os.unlink(effectiveRefPath) have_refmodule = False -if have_refmodule and not hasattr(sig_exists, "dict"): - print("*** wrong module without 'dict', removed:", shortpath) +dict_name = "sig_dict" +if have_refmodule and not hasattr(sig_exists, dict_name): + print("*** wrong module without '{dict_name}', removed:" + .format(**locals()), shortpath) os.unlink(effectiveRefPath) have_refmodule = False @@ -129,12 +131,12 @@ class TestSignaturesExists(unittest.TestCase): "Actual {len_act} {actual} vs. expected {len_exp} {expect}')" .format(**locals())) - for key, value in sig_exists.dict.items(): + for key, value in sig_exists.sig_dict.items(): name = key.rsplit(".", 1)[-1] if name in ("next", "__next__"): # ignore problematic cases continue if key not in found_sigs: - warn("missing key: '{}'".format(key)) + warn("missing key: '{}'".format(key), stacklevel=3) else: found_val = found_sigs[key] if type(value) is list and ( @@ -142,7 +144,7 @@ class TestSignaturesExists(unittest.TestCase): len(found_val) < len(value)): # We check that nothing got lost. But it is ok when an older # registry file does not know all variants, yet! - warn(multi_signature_msg(key, found_val, value)) + warn(multi_signature_msg(key, found_val, value), stacklevel=3) def test_signatures(self): found_sigs = enum_all() @@ -206,7 +208,7 @@ class TestSignaturesExists(unittest.TestCase): self.assertFalse(check_warnings(), "you ignore when arity got bigger") -tested_versions = (5, 6), (5, 9), (5, 11), (5, 12) +tested_versions = (5, 6), (5, 9), (5, 11), (5, 12), (5, 14) if not have_refmodule and is_ci and qt_version()[:2] in tested_versions: class TestFor_CI_Init(unittest.TestCase): diff --git a/sources/pyside2/tests/registry/init_platform.py b/sources/pyside2/tests/registry/init_platform.py index 31e212287..1c4261b4b 100644 --- a/sources/pyside2/tests/registry/init_platform.py +++ b/sources/pyside2/tests/registry/init_platform.py @@ -1,6 +1,6 @@ ############################################################################# ## -## Copyright (C) 2018 The Qt Company Ltd. +## Copyright (C) 2019 The Qt Company Ltd. ## Contact: https://www.qt.io/licensing/ ## ## This file is part of Qt for Python. @@ -201,39 +201,41 @@ class Formatter(object): """ def __init__(self, outfile): self.outfile = outfile + self.last_level = 0 def print(self, *args, **kw): print(*args, file=self.outfile, **kw) if self.outfile else None @contextmanager def module(self, mod_name): - self.mod_name = mod_name self.print("") self.print("# Module", mod_name) - self.print('if "{}" in sys.modules:'.format(mod_name)) - self.print(" dict.update({") + self.print("sig_dict.update({") yield - self.print(" })") + self.print(' }}) if "{mod_name}" in sys.modules else None'.format(**locals())) @contextmanager def klass(self, class_name, class_str): - self.class_name = class_name self.print() - self.print(" # class {}.{}:".format(self.mod_name, class_name)) + self.print("# class {self.mod_name}.{class_name}:".format(**locals())) yield @contextmanager def function(self, func_name, signature): - if self.class_name is None: - key = viskey = "{}".format(func_name) + if self.last_level > self.level: + self.print() + self.last_level = self.level + class_name = self.class_name + if class_name is None: + key = viskey = "{self.mod_name}.{func_name}".format(**locals()) else: - key = viskey = "{}.{}".format(self.class_name, func_name) + key = viskey = "{self.mod_name}.{class_name}.{func_name}".format(**locals()) if key.endswith("lY"): # Some classes like PySide2.QtGui.QContextMenuEvent have functions # globalX and the same with Y. The gerrit robot thinks that this # is a badly written "globally". Convince it by hiding this word. viskey = viskey[:-1] + '""Y' - self.print(' "{}": {},'.format(viskey, signature)) + self.print(' "{viskey}": {signature},'.format(**locals())) yield key @@ -268,7 +270,7 @@ def generate_all(): '''.format(module))) fmt.print("import sys") fmt.print("") - fmt.print("dict = {}") + fmt.print("sig_dict = {}") for mod_name in all_modules: enu.module(mod_name) fmt.print("# eof") diff --git a/sources/pyside2/tests/registry/util.py b/sources/pyside2/tests/registry/util.py index 415b8aa45..3033608e6 100644 --- a/sources/pyside2/tests/registry/util.py +++ b/sources/pyside2/tests/registry/util.py @@ -91,7 +91,7 @@ def check_warnings(): return True return False -def warn(message, category=None, stacklevel=1): +def warn(message, category=None, stacklevel=2): """Issue a warning with the default 'RuntimeWarning'""" if category is None: category = UserWarning diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp index a2b67b91b..85ce8f954 100644 --- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp @@ -4611,6 +4611,15 @@ void CppGenerator::writeEnumsInitialization(QTextStream &s, AbstractMetaEnumList } } +static QString mangleName(QString name) +{ + if ( name == QLatin1String("None") + || name == QLatin1String("False") + || name == QLatin1String("True")) + name += QLatin1Char('_'); + return name; +} + void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnum *cppEnum) { const AbstractMetaClass *enclosingClass = getProperEnclosingClassForEnum(cppEnum); @@ -4690,7 +4699,7 @@ void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnu Indentation indent(INDENT); s << INDENT << "PyObject *anonEnumItem = PyInt_FromLong(" << enumValueText << ");" << endl; s << INDENT << "if (PyDict_SetItemString(reinterpret_cast<PyTypeObject *>(reinterpret_cast<SbkObjectType *>(" << enclosingObjectVariable - << "))->tp_dict, \"" << enumValue->name() << "\", anonEnumItem) < 0)" << endl; + << "))->tp_dict, \"" << mangleName(enumValue->name()) << "\", anonEnumItem) < 0)" << endl; { Indentation indent(INDENT); s << INDENT << returnStatement(m_currentErrorCode) << endl; @@ -4699,7 +4708,7 @@ void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnu } s << INDENT << '}' << endl; } else { - s << INDENT << "if (PyModule_AddIntConstant(module, \"" << enumValue->name() << "\", "; + s << INDENT << "if (PyModule_AddIntConstant(module, \"" << mangleName(enumValue->name()) << "\", "; s << enumValueText << ") < 0)" << endl; { Indentation indent(INDENT); @@ -4712,7 +4721,7 @@ void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnu s << ((enclosingClass || hasUpperEnclosingClass) ? "createScopedEnumItem" : "createGlobalEnumItem"); s << '(' << enumVarTypeObj << ',' << endl; Indentation indent(INDENT); - s << INDENT << enclosingObjectVariable << ", \"" << enumValue->name() << "\", "; + s << INDENT << enclosingObjectVariable << ", \"" << mangleName(enumValue->name()) << "\", "; s << enumValueText << "))" << endl; s << INDENT << returnStatement(m_currentErrorCode) << endl; } @@ -4721,7 +4730,7 @@ void CppGenerator::writeEnumInitialization(QTextStream &s, const AbstractMetaEnu s << INDENT << "if (!Shiboken::Enum::createScopedEnumItem(" << enumVarTypeObj << ',' << endl; Indentation indent(INDENT); - s << INDENT << enumVarTypeObj<< ", \"" << enumValue->name() << "\", " + s << INDENT << enumVarTypeObj<< ", \"" << mangleName(enumValue->name()) << "\", " << enumValueText << "))" << endl << INDENT << returnStatement(m_currentErrorCode) << endl; } diff --git a/sources/shiboken2/libshiboken/sbkenum.cpp b/sources/shiboken2/libshiboken/sbkenum.cpp index 2dc785884..71fcf5f64 100644 --- a/sources/shiboken2/libshiboken/sbkenum.cpp +++ b/sources/shiboken2/libshiboken/sbkenum.cpp @@ -412,13 +412,6 @@ PyTypeObject *createScopedEnum(SbkObjectType *scope, const char *name, const cha static PyObject *createEnumItem(PyTypeObject *enumType, const char *itemName, long itemValue) { - char mangled[20]; - if (strcmp(itemName, "None") == 0 - || strcmp(itemName, "False") == 0 || strcmp(itemName, "True") == 0) { - strcpy(mangled, itemName); - strcat(mangled, "_"); - itemName = mangled; - } PyObject *enumItem = newItem(enumType, itemValue, itemName); if (PyDict_SetItemString(enumType->tp_dict, itemName, enumItem) < 0) return nullptr; 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 b84a20e16..2e4d67186 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 @@ -84,6 +84,7 @@ class ExactEnumerator(object): def module(self, mod_name): __import__(mod_name) + self.fmt.mod_name = mod_name with self.fmt.module(mod_name): module = sys.modules[mod_name] members = inspect.getmembers(module, inspect.isclass) @@ -93,7 +94,7 @@ class ExactEnumerator(object): for class_name, klass in members: ret.update(self.klass(class_name, klass)) if isinstance(klass, EnumType): - self.enum(klass) + raise SystemError("implement enum instances at module level") for func_name, func in functions: ret.update(self.function(func_name, func)) return ret @@ -114,26 +115,41 @@ class ExactEnumerator(object): name = modname + "." + base.__name__ bases_list.append(name) class_str = "{}({})".format(class_name, ", ".join(bases_list)) - with self.fmt.klass(class_name, class_str): - ret = self.result_type() - # class_members = inspect.getmembers(klass) - # gives us also the inherited things. - class_members = sorted(list(klass.__dict__.items())) - subclasses = [] - functions = [] - for thing_name, thing in class_members: - if inspect.isclass(thing): - subclass_name = ".".join((class_name, thing_name)) - subclasses.append((subclass_name, thing)) - elif inspect.isroutine(thing): - func_name = thing_name.split(".")[0] # remove ".overload" + ret = self.result_type() + # class_members = inspect.getmembers(klass) + # gives us also the inherited things. + class_members = sorted(list(klass.__dict__.items())) + subclasses = [] + functions = [] + enums = [] + + for thing_name, thing in class_members: + if inspect.isclass(thing): + subclass_name = ".".join((class_name, thing_name)) + subclasses.append((subclass_name, thing)) + elif inspect.isroutine(thing): + func_name = thing_name.split(".")[0] # remove ".overload" + signature = getattr(thing, "__signature__", None) + if signature is not None: functions.append((func_name, thing)) + elif type(type(thing)) is EnumType: + enums.append((thing_name, thing)) + init_signature = getattr(klass, "__signature__", None) + enums.sort(key=lambda tup: tup[1]) # sort by enum value + self.fmt.have_body = bool(subclasses or functions or enums or init_signature) + + with self.fmt.klass(class_name, class_str): self.fmt.level += 1 + self.fmt.class_name = class_name + if hasattr(self.fmt, "enum"): + # this is an optional feature + for enum_name, value in enums: + with self.fmt.enum(class_name, enum_name, int(value)): + pass for subclass_name, subclass in subclasses: ret.update(self.klass(subclass_name, subclass)) - if isinstance(subclass, EnumType): - self.enum(subclass) - ret = self.function("__init__", klass) + self.fmt.class_name = class_name + ret.update(self.function("__init__", klass)) for func_name, func in functions: func_kind = get_signature(func, "__func_kind__") modifier = func_kind if func_kind in ( @@ -145,24 +161,13 @@ class ExactEnumerator(object): def function(self, func_name, func, modifier=None): self.fmt.level += 1 ret = self.result_type() - signature = getattr(func, '__signature__', None) + signature = func.__signature__ if signature is not None: with self.fmt.function(func_name, signature, modifier) as key: ret[key] = signature self.fmt.level -= 1 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 - self._after_enum = True - def stringify(signature): if isinstance(signature, list): |
