From 4379a97592fb282c6e6acc9185a68953e7c46e3d Mon Sep 17 00:00:00 2001 From: Christian Tismer Date: Thu, 30 Nov 2017 19:25:59 +0100 Subject: Fix signature registry on Python2 with .pyc files, part 2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is unfortunately another bad side effect with .pyc files. I had to make sure that not the __file__ attribute is used, but the correct filename is computed, because __file__ can refer to the .pyc file under certain circumstances. Improved error handling, more file type checks and short filenames relative to the project path added for convenience. Task-number: PYSIDE-510 Change-Id: Ia0002fdfb382b7d3681156b1aef42739eb22dcc9 Reviewed-by: Simo Fält --- sources/pyside2/tests/registry/existence_test.py | 48 ++++++++++++++++-------- sources/pyside2/tests/registry/init_platform.py | 40 ++++---------------- sources/pyside2/tests/registry/util.py | 6 +++ 3 files changed, 45 insertions(+), 49 deletions(-) (limited to 'sources/pyside2/tests') diff --git a/sources/pyside2/tests/registry/existence_test.py b/sources/pyside2/tests/registry/existence_test.py index 7627eeab2..cdb6f362f 100644 --- a/sources/pyside2/tests/registry/existence_test.py +++ b/sources/pyside2/tests/registry/existence_test.py @@ -43,25 +43,37 @@ import os import sys import unittest import warnings -from init_platform import enum_all, generate_all, is_ci, outname, outpath -from util import isolate_warnings, check_warnings +from textwrap import dedent +from init_platform import enum_all, generate_all, is_ci, module, refpath +from util import isolate_warnings, check_warnings, suppress_warnings from PySide2 import * from PySide2.QtCore import __version__ -refmodule_name = outname[:-3] # no .py -pyc = os.path.splitext(outpath)[0] + ".pyc" -if os.path.exists(pyc) and not os.path.exists(outname): +pyc = os.path.splitext(refpath)[0] + ".pyc" +if os.path.exists(pyc) and not os.path.exists(refpath): # on Python2 the pyc file would be imported os.unlink(pyc) -sys.path.insert(0, os.path.dirname(__file__)) +home_dir = refpath +for _ in "abcde": + home_dir = os.path.dirname(home_dir) +shortpath = os.path.relpath(refpath, home_dir) try: - exec("import {} as sig_exists".format(refmodule_name)) - print("found:", refmodule_name) + exec("import {} as sig_exists".format(module)) + print("found:", shortpath) have_refmodule = True except ImportError: - print("*** not found:", refmodule_name) + print("*** not found:", shortpath) have_refmodule = False +except SyntaxError: + print("*** not a python file, removed:", shortpath) + os.unlink(refpath) + have_refmodule = False +if have_refmodule and not hasattr(sig_exists, "dict"): + print("*** wrong module without 'dict', removed:", shortpath) + os.unlink(refpath) + have_refmodule = False + @unittest.skipIf(not have_refmodule, "not activated for this platform or version") @@ -87,12 +99,12 @@ class TestSignaturesExists(unittest.TestCase): found_sigs = enum_all() # make sure that errors are actually raised found_sigs.pop(list(found_sigs.keys())[42]) - with isolate_warnings(): + with isolate_warnings(), suppress_warnings(): for key, value in sig_exists.dict.items(): if key not in found_sigs: - warnings.warn("ignore missing key: '{}'".format(key), RuntimeWarning) + warnings.warn("missing key: '{}'".format(key), RuntimeWarning) elif isinstance(value, list) and len(value) != len(found_sigs[key]): - warnings.warn("ignore different sig length: '{}'".format(key), RuntimeWarning) + warnings.warn("different sig length: '{}'".format(key), RuntimeWarning) self.assertTrue(check_warnings()) version = tuple(map(int, __version__.split("."))) @@ -107,12 +119,16 @@ if not have_refmodule and is_ci and version[:2] in tested_versions: """ generate_all() sys.stderr.flush() - print("BEGIN", outpath, file=sys.stderr) - with open(outpath) as f: + print("BEGIN_FILE", shortpath, file=sys.stderr) + with open(refpath) as f: print(f.read(), file=sys.stderr) - print("END", outpath, file=sys.stderr) + print("END_FILE", shortpath, file=sys.stderr) sys.stderr.flush() - raise RuntimeError("This is the initial call. You should check this file in.") + raise RuntimeError(dedent(""" + {line} + ** This is the initial call. You should check this file in: + ** {} + **""").format(shortpath, line=79 * "*")) if __name__ == '__main__': unittest.main() diff --git a/sources/pyside2/tests/registry/init_platform.py b/sources/pyside2/tests/registry/init_platform.py index ea8eb2af2..5b6558806 100644 --- a/sources/pyside2/tests/registry/init_platform.py +++ b/sources/pyside2/tests/registry/init_platform.py @@ -59,10 +59,11 @@ version_id = __version__.replace(".", "_") is_ci = os.environ.get("QTEST_ENVIRONMENT", "") == "ci" # Python2 legacy: Correct 'linux2' to 'linux', recommended way. platform = 'linux' if sys.platform.startswith('linux') else sys.platform -outname = "exists_{}_{}{}.py".format(platform, version_id, +module = "exists_{}_{}{}".format(platform, version_id, "_ci" if is_ci else "") -outpath = os.path.join(os.path.dirname(__file__), outname) +refpath = os.path.join(os.path.dirname(__file__), module + ".py") outfile = None +sourcepath = os.path.splitext(__file__)[0] + ".py" # make sure not to get .pyc def xprint(*args, **kw): if outfile: @@ -144,9 +145,8 @@ def enum_module(mod_name): def generate_all(): global outfile - with open(outpath, "w") as outfile: - with open(__file__) as f: - lines = f.readlines() + with open(refpath, "w") as outfile, open(sourcepath) as f: + lines = f.readlines() license_line = next((lno for lno, line in enumerate(lines) if "$QT_END_LICENSE$" in line)) xprint("".join(lines[:license_line + 3])) @@ -165,35 +165,9 @@ def enum_all(): ret.update(enum_module(mod_name)) return ret -# This function exists because I forgot to sort the files in the first place. -def sort_dict(fname): - with open(fname) as f: - lines = f.readlines() - out = [] - while lines: - line = lines.pop(0) - if not line.lstrip().startswith('"'): - out.append(line) - continue - out.append(line) - buf = [] # leave __init__ in place - line = lines.pop(0) - while line.lstrip().startswith('"'): - buf.append(line) - line = lines.pop(0) - buf.sort() - out.extend(buf) - out.append(line) - with open(fname, "w") as f: - f.writelines(out) - def __main__(): - if sys.argv[1:]: - fname = sys.argv[1] - print("we are just sorting", fname) - sort_dict(fname) - sys.exit(0) - print("+++ generating {}. You should check this file in.".format(outname)) + print("+++ generating {}. You should probably check this file in." + .format(refpath)) generate_all() if __name__ == "__main__": diff --git a/sources/pyside2/tests/registry/util.py b/sources/pyside2/tests/registry/util.py index 5d0602b2a..d873a7d66 100644 --- a/sources/pyside2/tests/registry/util.py +++ b/sources/pyside2/tests/registry/util.py @@ -72,6 +72,12 @@ def isolate_warnings(): if warn is None: delattr(mod, warn_name) +@contextmanager +def suppress_warnings(): + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + yield + def check_warnings(): for name, mod in sys.modules.items(): if mod: -- cgit v1.2.3 From 4f11db4232d7ce5ac415d36d86fbf6e92f6e88a1 Mon Sep 17 00:00:00 2001 From: Christian Tismer Date: Fri, 1 Dec 2017 16:53:58 +0100 Subject: Unify signature registry for py2 / py3 and clean up It turned out that there are tiny differences between Python2 and Python3 which make the versions of the registry almost, but not totally equal. There are functions which are slot wrappers in Python2 instead of method wrappers in Python3, and we currently don't support slot wrappers. There are other tiny differences when we switch to Qt 5.9, too. Initially, I thought to split the files for Python2 and Python3, but then it turned out that the problems vanish when we ignore the 'next' and '__next__' functions in both python versions. The filter function is both applied to the generating function and the testing function. Therefore we can keep the existing data intact. I further removed an indentation leftover in cppgenerator.cpp, fixed handling of duplicate entries and improved modularisation of the signature enumerator and formatter. This part will later be moved into the signature library. Task-number: PYSIDE-510 Change-Id: I18f5e8f08fb9b07534003919abe55ab4dafeb2c2 Reviewed-by: Alexandru Croitor --- sources/pyside2/tests/registry/existence_test.py | 17 +- sources/pyside2/tests/registry/init_platform.py | 215 +++++++++++++++-------- sources/pyside2/tests/registry/signature_test.py | 7 +- sources/pyside2/tests/registry/util.py | 6 + 4 files changed, 159 insertions(+), 86 deletions(-) (limited to 'sources/pyside2/tests') diff --git a/sources/pyside2/tests/registry/existence_test.py b/sources/pyside2/tests/registry/existence_test.py index cdb6f362f..e7cadd54d 100644 --- a/sources/pyside2/tests/registry/existence_test.py +++ b/sources/pyside2/tests/registry/existence_test.py @@ -42,10 +42,9 @@ from __future__ import print_function, absolute_import import os import sys import unittest -import warnings from textwrap import dedent from init_platform import enum_all, generate_all, is_ci, module, refpath -from util import isolate_warnings, check_warnings, suppress_warnings +from util import isolate_warnings, check_warnings, suppress_warnings, warn from PySide2 import * from PySide2.QtCore import __version__ @@ -88,10 +87,13 @@ class TestSignaturesExists(unittest.TestCase): found_sigs = enum_all() with isolate_warnings(): for key, value in sig_exists.dict.items(): + name = key.rsplit(".", 1)[-1] + if name in ("next", "__next__"): # ignore problematic cases + continue if key not in found_sigs: - warnings.warn("missing key: '{}'".format(key), RuntimeWarning) + warn("missing key: '{}'".format(key)) elif isinstance(value, list) and len(value) != len(found_sigs[key]): - warnings.warn("different sig length: '{}'".format(key), RuntimeWarning) + warn("multi-signature count mismatch: '{}'".format(key)) if is_ci and check_warnings(): raise RuntimeError("There are errors, see above.") @@ -101,10 +103,13 @@ class TestSignaturesExists(unittest.TestCase): found_sigs.pop(list(found_sigs.keys())[42]) with isolate_warnings(), suppress_warnings(): for key, value in sig_exists.dict.items(): + name = key.rsplit(".", 1)[-1] + if name in ("next", "__next__"): # ignore problematic cases + continue if key not in found_sigs: - warnings.warn("missing key: '{}'".format(key), RuntimeWarning) + warn("missing key: '{}'".format(key)) elif isinstance(value, list) and len(value) != len(found_sigs[key]): - warnings.warn("different sig length: '{}'".format(key), RuntimeWarning) + warn("multi-signature count mismatch: '{}'".format(key)) self.assertTrue(check_warnings()) version = tuple(map(int, __version__.split("."))) diff --git a/sources/pyside2/tests/registry/init_platform.py b/sources/pyside2/tests/registry/init_platform.py index 5b6558806..2a0b66e06 100644 --- a/sources/pyside2/tests/registry/init_platform.py +++ b/sources/pyside2/tests/registry/init_platform.py @@ -49,6 +49,8 @@ One file is generated with all signatures of a platform and version. import sys import os import PySide2 +from contextlib import contextmanager +from textwrap import dedent all_modules = list("PySide2." + x for x in PySide2.__all__) @@ -56,29 +58,105 @@ from PySide2.support.signature import inspect from PySide2.QtCore import __version__ version_id = __version__.replace(".", "_") +is_py3 = sys.version_info[0] == 3 is_ci = os.environ.get("QTEST_ENVIRONMENT", "") == "ci" # Python2 legacy: Correct 'linux2' to 'linux', recommended way. platform = 'linux' if sys.platform.startswith('linux') else sys.platform -module = "exists_{}_{}{}".format(platform, version_id, - "_ci" if is_ci else "") +module = "exists_{}_{}{}".format(platform, version_id, "_ci" if is_ci else "") refpath = os.path.join(os.path.dirname(__file__), module + ".py") -outfile = None -sourcepath = os.path.splitext(__file__)[0] + ".py" # make sure not to get .pyc +# Make sure not to get .pyc in Python2. +sourcepath = os.path.splitext(__file__)[0] + ".py" + + +class Formatter(object): + """ + Formatter is formatting the signature listing of an enumerator. + + It is written as context managers in order to avoid many callbacks. + The division in formatter and enumerator is done to keep the + unrelated tasks of enumeration and formatting apart. + """ + def __init__(self, outfile): + self.outfile = outfile + + 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({") + yield + self.print(" })") + + @contextmanager + def klass(self, class_name): + self.class_name = class_name + self.print() + self.print(" # class {}.{}:".format(self.mod_name, class_name)) + yield + + @contextmanager + def function(self, func_name, signature): + key = viskey = "{}.{}".format(self.class_name, func_name) + 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)) + yield key + + +class ExactEnumerator(object): + """ + ExactEnumerator enumerates all signatures in a module as they are. + + This class is used for generating complete listings of all signatures. + An appropriate formatter should be supplied, if printable output + is desired. + """ + def __init__(self, formatter, result_type=dict): + self.fmt = formatter + self.result_type = result_type + + def module(self, mod_name): + __import__(mod_name) + with self.fmt.module(mod_name): + module = sys.modules[mod_name] + members = inspect.getmembers(module, inspect.isclass) + ret = self.result_type() + for class_name, klass in members: + ret.update(self.klass(class_name, klass)) + return ret + + def klass(self, class_name, klass): + with self.fmt.klass(class_name): + ret = self.function("__init__", klass) + # class_members = inspect.getmembers(klass) + # gives us also the inherited things. + class_members = sorted(list(klass.__dict__.items())) + for func_name, func in class_members: + ret.update(self.function(func_name, func)) + return ret + + def function(self, func_name, func): + ret = self.result_type() + signature = getattr(func, '__signature__', None) + if signature is not None: + with self.fmt.function(func_name, signature) as key: + ret[key] = signature + return ret -def xprint(*args, **kw): - if outfile: - print(*args, file=outfile, **kw) def simplify(signature): if isinstance(signature, list): - ret = list(simplify(sig) for sig in signature) # remove duplicates which still sometimes occour: - things = set(ret) - if len(things) != len(ret): - ret = list(things) - if len(ret) == 1: - ret = ret[0] - return sorted(ret) + ret = set(simplify(sig) for sig in signature) + return sorted(ret) if len(ret) > 1 else list(ret)[0] ret = [] for pv in signature.parameters.values(): txt = str(pv) @@ -93,77 +171,60 @@ def simplify(signature): ret.append(txt) return tuple(ret) -def begin_module(mod_name): - xprint("") - xprint("# Module", mod_name) - xprint('if "{}" in sys.modules:'.format(mod_name)) - xprint(" dict.update({") - -def end_module(mod_name): - xprint(" })") - -def begin_class(mod_name, class_name): - xprint() - xprint(" # class {}.{}:".format(mod_name, class_name)) - -def end_class(mod_name, class_name): - pass - -def show_signature(key, signature): - if key.endswith("lY"): - # make the robot shut up: - key = key[:-1] + '"+"Y' - xprint(' "{}": {},'.format(key, signature)) - -def enum_module(mod_name): - __import__(mod_name) - begin_module(mod_name) - module = sys.modules[mod_name] - members = inspect.getmembers(module, inspect.isclass) - ret = {} - for class_name, klass in members: - begin_class(mod_name, class_name) - signature = getattr(klass, '__signature__', None) - # class_members = inspect.getmembers(klass) - # gives us also the inherited things. - if signature is not None: - signature = simplify(signature) - key = "{}.{}".format(class_name, "__init__") - ret[key] = signature - show_signature(key, signature) - class_members = sorted(list(klass.__dict__.items())) - for func_name, func in class_members: - signature = getattr(func, '__signature__', None) - if signature is not None: - signature = simplify(signature) - key = "{}.{}".format(class_name, func_name) - ret[key] = signature - show_signature(key, signature) - end_class(mod_name, class_name) - end_module(mod_name) + +class SimplifyingEnumerator(ExactEnumerator): + """ + SimplifyingEnumerator enumerates all signatures in a module filtered. + + There are no default values, no variable + names and no self parameter. Only types are present after simplification. + The functions 'next' resp. '__next__' are removed + to make the output identical for Python 2 and 3. + An appropriate formatter should be supplied, if printable output + is desired. + """ + + def function(self, func_name, func): + ret = self.result_type() + signature = getattr(func, '__signature__', None) + sig = simplify(signature) if signature is not None else None + if sig is not None and func_name not in ("next", "__next__"): + with self.fmt.function(func_name, sig) as key: + ret[key] = sig + return ret + + +def enum_all(): + fmt = Formatter(None) + enu = SimplifyingEnumerator(fmt) + ret = enu.result_type() + for mod_name in all_modules: + ret.update(enu.module(mod_name)) return ret def generate_all(): - global outfile with open(refpath, "w") as outfile, open(sourcepath) as f: + fmt = Formatter(outfile) + enu = SimplifyingEnumerator(fmt) lines = f.readlines() license_line = next((lno for lno, line in enumerate(lines) if "$QT_END_LICENSE$" in line)) - xprint("".join(lines[:license_line + 3])) - xprint("import sys") - xprint("") - xprint("dict = {}") + fmt.print("".join(lines[:license_line + 3])) + fmt.print(dedent('''\ + """ + This file contains the simplified signatures for all functions in PySide + for module '{}'. There are no default values, no variable + names and no self parameter. Only types are present after simplification. + The functions 'next' resp. '__next__' are removed + to make the output identical for Python 2 and 3. + """ + '''.format(module))) + fmt.print("import sys") + fmt.print("") + fmt.print("dict = {}") for mod_name in all_modules: - enum_module(mod_name) - xprint("# eof") - -def enum_all(): - global outfile - outfile = None - ret = {} - for mod_name in all_modules: - ret.update(enum_module(mod_name)) - return ret + enu.module(mod_name) + fmt.print("# eof") def __main__(): print("+++ generating {}. You should probably check this file in." diff --git a/sources/pyside2/tests/registry/signature_test.py b/sources/pyside2/tests/registry/signature_test.py index 949244dc3..105f46e15 100644 --- a/sources/pyside2/tests/registry/signature_test.py +++ b/sources/pyside2/tests/registry/signature_test.py @@ -85,9 +85,9 @@ def enum_module(mod_name): else: dprint(" def __init__" + str(signature)) count += 1 - class_members = list(klass.__dict__.items()) have_sig = signature is not None have_members = 0 + class_members = sorted(list(klass.__dict__.items())) for func_name, func in class_members: signature = getattr(func, '__signature__', None) if signature is not None: @@ -110,8 +110,9 @@ def enum_all(): for mod_name in all_modules: result[mod_name] = enum_module(mod_name) total += result[mod_name] - pprint(result if sys.version_info >= (3,) else list(result.items())) - print("Total", total) + pprint(result if sys.version_info >= (3,) else list(result.items()), + stream=sys.stderr) + print("Total", total, file=sys.stderr) return result diff --git a/sources/pyside2/tests/registry/util.py b/sources/pyside2/tests/registry/util.py index d873a7d66..7e048cb24 100644 --- a/sources/pyside2/tests/registry/util.py +++ b/sources/pyside2/tests/registry/util.py @@ -91,4 +91,10 @@ def check_warnings(): return True return False +def warn(message, category=None, stacklevel=1): + """Issue a warning with the default 'RuntimeWarning'""" + if category is None: + category = UserWarning + warnings.warn(message, category, stacklevel) + # eof -- cgit v1.2.3 From 54457efbf96bf644f44a9ac1b55dc98847dad73e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 8 Dec 2017 08:56:22 +0100 Subject: Fix QtCore test bug829 to run on Windows The test used Python functionality to create a temporary file which caused an access error on Windows, apparently due to the file still being open. Besides, the temporary file was leaked. Rewrite using QTemporaryFile and make sure the file is closed and the QTemporaryFile is deleted before using it and delete it in __del__(). Task-number: PYSIDE-431 Change-Id: I5d63e76ead7169d9f3f2267ee53aa91b601a3968 Reviewed-by: Christian Tismer --- sources/pyside2/tests/QtCore/bug_829.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'sources/pyside2/tests') diff --git a/sources/pyside2/tests/QtCore/bug_829.py b/sources/pyside2/tests/QtCore/bug_829.py index 5b14f7b59..730a2e9ed 100644 --- a/sources/pyside2/tests/QtCore/bug_829.py +++ b/sources/pyside2/tests/QtCore/bug_829.py @@ -30,21 +30,36 @@ # Test case for PySide bug 829 import unittest -from PySide2.QtCore import QSettings -import tempfile +from PySide2.QtCore import QDir, QSettings, QTemporaryFile +import os class QVariantConversions(unittest.TestCase): + + _confFileName = None + def testDictionary(self): - confFile = tempfile.NamedTemporaryFile(delete=False) - s = QSettings(confFile.name, QSettings.IniFormat) + confFile = QTemporaryFile(QDir.tempPath() + '/pysidebug829_XXXXXX.ini') + confFile.setAutoRemove(False) + self.assertTrue(confFile.open()) + confFile.close() + self._confFileName = confFile.fileName() + del confFile + s = QSettings(self._confFileName, QSettings.IniFormat) + self.assertEqual(s.status(), QSettings.NoError) # Save value s.setValue('x', {1: 'a'}) s.sync() + self.assertEqual(s.status(), QSettings.NoError) del s # Restore value - s = QSettings(confFile.name, QSettings.IniFormat) + s = QSettings(self._confFileName, QSettings.IniFormat) + self.assertEqual(s.status(), QSettings.NoError) self.assertEqual(s.value('x'), {1: 'a'}) + def __del__(self): + if self._confFileName is not None: + os.unlink(QDir.toNativeSeparators(self._confFileName)) + if __name__ == '__main__': unittest.main() -- cgit v1.2.3 From cd1037060e0cbc263e601fb67fbd40d85c8801a1 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 20 Dec 2017 15:10:24 +0100 Subject: Signature existence tests: Fall back to previous patch releases In case the reference file for a given patch release does not exist, fall back to a previous one. Replace variables in the init_platform module by functions getEffectiveRefPath(), getRefPath(). Task-number: PYSIDE-510 Change-Id: I208f4618be6e20be5023938850ca0eacc43b0101 Reviewed-by: Christian Tismer --- sources/pyside2/tests/registry/existence_test.py | 35 ++++++++++++++---------- sources/pyside2/tests/registry/init_platform.py | 34 ++++++++++++++++++++--- 2 files changed, 51 insertions(+), 18 deletions(-) (limited to 'sources/pyside2/tests') diff --git a/sources/pyside2/tests/registry/existence_test.py b/sources/pyside2/tests/registry/existence_test.py index e7cadd54d..8f3c568a3 100644 --- a/sources/pyside2/tests/registry/existence_test.py +++ b/sources/pyside2/tests/registry/existence_test.py @@ -43,20 +43,28 @@ import os import sys import unittest from textwrap import dedent -from init_platform import enum_all, generate_all, is_ci, module, refpath +from init_platform import (enum_all, generate_all, is_ci, + getEffectiveRefPath, getRefPath, qtVersion) from util import isolate_warnings, check_warnings, suppress_warnings, warn from PySide2 import * -from PySide2.QtCore import __version__ -pyc = os.path.splitext(refpath)[0] + ".pyc" -if os.path.exists(pyc) and not os.path.exists(refpath): +refPath = getRefPath() +effectiveRefPath = getEffectiveRefPath() +effectiveRefPathRoot = os.path.splitext(effectiveRefPath)[0] +pyc = effectiveRefPathRoot + ".pyc" +if os.path.exists(pyc) and not os.path.exists(effectiveRefPath): # on Python2 the pyc file would be imported os.unlink(pyc) +module = os.path.basename(effectiveRefPathRoot) -home_dir = refpath +if refPath != effectiveRefPath: + print("*** Falling back to ", effectiveRefPath, " since expected ", + refPath, " does not exist") + +home_dir = effectiveRefPath for _ in "abcde": home_dir = os.path.dirname(home_dir) -shortpath = os.path.relpath(refpath, home_dir) +shortpath = os.path.relpath(effectiveRefPath, home_dir) try: exec("import {} as sig_exists".format(module)) print("found:", shortpath) @@ -66,11 +74,11 @@ except ImportError: have_refmodule = False except SyntaxError: print("*** not a python file, removed:", shortpath) - os.unlink(refpath) + os.unlink(effectiveRefPath) have_refmodule = False if have_refmodule and not hasattr(sig_exists, "dict"): print("*** wrong module without 'dict', removed:", shortpath) - os.unlink(refpath) + os.unlink(effectiveRefPath) have_refmodule = False @@ -112,10 +120,9 @@ class TestSignaturesExists(unittest.TestCase): warn("multi-signature count mismatch: '{}'".format(key)) self.assertTrue(check_warnings()) -version = tuple(map(int, __version__.split("."))) tested_versions = (5, 6), (5, 9), (5, 11) -if not have_refmodule and is_ci and version[:2] in tested_versions: +if not have_refmodule and is_ci and qtVersion()[:2] in tested_versions: class TestFor_CI_Init(unittest.TestCase): """ This helper class generates the reference file for CI. @@ -124,16 +131,16 @@ if not have_refmodule and is_ci and version[:2] in tested_versions: """ generate_all() sys.stderr.flush() - print("BEGIN_FILE", shortpath, file=sys.stderr) - with open(refpath) as f: + print("BEGIN_FILE", refPath, file=sys.stderr) + with open(refPath) as f: print(f.read(), file=sys.stderr) - print("END_FILE", shortpath, file=sys.stderr) + print("END_FILE", refPath, file=sys.stderr) sys.stderr.flush() raise RuntimeError(dedent(""" {line} ** This is the initial call. You should check this file in: ** {} - **""").format(shortpath, line=79 * "*")) + **""").format(refPath, line=79 * "*")) if __name__ == '__main__': unittest.main() diff --git a/sources/pyside2/tests/registry/init_platform.py b/sources/pyside2/tests/registry/init_platform.py index 2a0b66e06..ffe6e22fc 100644 --- a/sources/pyside2/tests/registry/init_platform.py +++ b/sources/pyside2/tests/registry/init_platform.py @@ -57,16 +57,42 @@ all_modules = list("PySide2." + x for x in PySide2.__all__) from PySide2.support.signature import inspect from PySide2.QtCore import __version__ -version_id = __version__.replace(".", "_") is_py3 = sys.version_info[0] == 3 is_ci = os.environ.get("QTEST_ENVIRONMENT", "") == "ci" # Python2 legacy: Correct 'linux2' to 'linux', recommended way. platform = 'linux' if sys.platform.startswith('linux') else sys.platform -module = "exists_{}_{}{}".format(platform, version_id, "_ci" if is_ci else "") -refpath = os.path.join(os.path.dirname(__file__), module + ".py") # Make sure not to get .pyc in Python2. sourcepath = os.path.splitext(__file__)[0] + ".py" +def qtVersion(): + return tuple(map(int, __version__.split("."))) + +# Format a registry file name for version +def _registryFileName(version): + name = "exists_{}_{}_{}_{}{}.py".format(platform, + version[0], version[1], version[2], "_ci" if is_ci else "") + return os.path.join(os.path.dirname(__file__), name) + +# Return the expected registry file name +def getRefPath(): + return _registryFileName(qtVersion()) + +# Return the registry file name, either that of the current +# version or fall back to a previous patch release +def getEffectiveRefPath(): + refpath = getRefPath() + if os.path.exists(refpath): + return refpath + version = qtVersion() + majorVersion = version[0] + minorVersion = version[1] + patchVersion = version[2] + while patchVersion >= 0: + file = _registryFileName((majorVersion, minorVersion, patchVersion)) + if os.path.exists(file): + return file + patchVersion = patchVersion - 1 + return refpath class Formatter(object): """ @@ -203,7 +229,7 @@ def enum_all(): return ret def generate_all(): - with open(refpath, "w") as outfile, open(sourcepath) as f: + with open(refPath(), "w") as outfile, open(sourcepath) as f: fmt = Formatter(outfile) enu = SimplifyingEnumerator(fmt) lines = f.readlines() -- cgit v1.2.3 From 939150289d13b40882f7247d05213a0418076810 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 3 Jan 2018 11:03:19 +0100 Subject: Signature existence tests: Fix generation of the signature file Amends cd1037060e0cbc263e601fb67fbd40d85c8801a1. Task-number: PYSIDE-510 Change-Id: Ic93a6ef4ab846b07b369f691f52240aeedbfbec3 Reviewed-by: Christian Tismer --- sources/pyside2/tests/registry/existence_test.py | 6 +++--- sources/pyside2/tests/registry/init_platform.py | 6 ++++-- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'sources/pyside2/tests') diff --git a/sources/pyside2/tests/registry/existence_test.py b/sources/pyside2/tests/registry/existence_test.py index 8f3c568a3..3c5b7e545 100644 --- a/sources/pyside2/tests/registry/existence_test.py +++ b/sources/pyside2/tests/registry/existence_test.py @@ -131,16 +131,16 @@ if not have_refmodule and is_ci and qtVersion()[:2] in tested_versions: """ generate_all() sys.stderr.flush() - print("BEGIN_FILE", refPath, file=sys.stderr) + print("BEGIN_FILE", shortpath, file=sys.stderr) with open(refPath) as f: print(f.read(), file=sys.stderr) - print("END_FILE", refPath, file=sys.stderr) + print("END_FILE", shortpath, file=sys.stderr) sys.stderr.flush() raise RuntimeError(dedent(""" {line} ** This is the initial call. You should check this file in: ** {} - **""").format(refPath, line=79 * "*")) + **""").format(shortpath, line=79 * "*")) if __name__ == '__main__': unittest.main() diff --git a/sources/pyside2/tests/registry/init_platform.py b/sources/pyside2/tests/registry/init_platform.py index ffe6e22fc..a8e692d98 100644 --- a/sources/pyside2/tests/registry/init_platform.py +++ b/sources/pyside2/tests/registry/init_platform.py @@ -229,7 +229,9 @@ def enum_all(): return ret def generate_all(): - with open(refPath(), "w") as outfile, open(sourcepath) as f: + refPath = getRefPath() + module = os.path.basename(os.path.splitext(refPath)[0]) + with open(refPath, "w") as outfile, open(sourcepath) as f: fmt = Formatter(outfile) enu = SimplifyingEnumerator(fmt) lines = f.readlines() @@ -254,7 +256,7 @@ def generate_all(): def __main__(): print("+++ generating {}. You should probably check this file in." - .format(refpath)) + .format(getRefPath())) generate_all() if __name__ == "__main__": -- cgit v1.2.3