From 478947236afdb8ce3f30eb2719b5102a55cd7c5c Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Sun, 20 Nov 2022 09:26:50 -0500 Subject: [PATCH 1/9] mypy==0.991 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 23a6e96..35ecd3d 100644 --- a/setup.py +++ b/setup.py @@ -51,7 +51,7 @@ def find_version(*file_paths): package_data={"PyQt5-stubs": ['*.pyi']}, packages=["PyQt5-stubs"], extras_require={ - "dev": ["mypy==0.930", "pytest", "pytest-xvfb"], + "dev": ["mypy==0.991", "pytest", "pytest-xvfb"], }, classifiers=[ "Development Status :: 5 - Production/Stable", From 5c9df5a710ed3d73d218193b00d4012bafa15083 Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Sat, 26 Nov 2022 10:20:29 -0500 Subject: [PATCH 2/9] old mypy for old python --- setup.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 35ecd3d..6a18bf1 100644 --- a/setup.py +++ b/setup.py @@ -51,7 +51,12 @@ def find_version(*file_paths): package_data={"PyQt5-stubs": ['*.pyi']}, packages=["PyQt5-stubs"], extras_require={ - "dev": ["mypy==0.991", "pytest", "pytest-xvfb"], + "dev": [ + "mypy==0.991; python_version >= '3.7'", + "mypy==0.930; python_version < '3.7'", + "pytest", + "pytest-xvfb", + ], }, classifiers=[ "Development Status :: 5 - Production/Stable", From 3588f184faf10d9d2ea2b90e69e34c546b38076a Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Mon, 28 Nov 2022 11:05:24 -0500 Subject: [PATCH 3/9] Update setup.py --- setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 6a18bf1..451f686 100644 --- a/setup.py +++ b/setup.py @@ -53,7 +53,8 @@ def find_version(*file_paths): extras_require={ "dev": [ "mypy==0.991; python_version >= '3.7'", - "mypy==0.930; python_version < '3.7'", + # https://github.com/python/mypy/commit/dc118e293203863ab1007699b2cecf0f26ddfa22 + "mypy==0.980; python_version < '3.7'", "pytest", "pytest-xvfb", ], From 77ead26dd3a73affe9875a8fdc5788b4bf7e842b Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Mon, 28 Nov 2022 11:30:01 -0500 Subject: [PATCH 4/9] monkey patch mypy.stubtest._verify_final() to be a noop --- stubtest_wrapper.py | 33 +++++++++++++++++++++++++++++++++ tox.ini | 3 +-- 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 stubtest_wrapper.py diff --git a/stubtest_wrapper.py b/stubtest_wrapper.py new file mode 100644 index 0000000..2a5027e --- /dev/null +++ b/stubtest_wrapper.py @@ -0,0 +1,33 @@ +# workaround for https://github.com/python/mypy/issues/14196 + +import sys +import typing + +import mypy.stubtest + + +def noop_generator(*args, **kwargs) -> typing.Iterator[object]: + return + yield # make it a generator as the original is + + +def maybe_monkey_patch() -> None: + if not hasattr(mypy.stubtest, "_verify_final"): + print("mypy.stubtest._verify_final does not exist, skipping monkey patching") + return + + if not callable(mypy.stubtest._verify_final): + print("mypy.stubtest._verify_final is not a callable, skipping monkey patching") + return + + mypy.stubtest._verify_final = noop_generator + return + + +def main() -> int: + maybe_monkey_patch() + + return mypy.stubtest.main() + + +sys.exit(main()) diff --git a/tox.ini b/tox.ini index 1dc709a..f5657c7 100644 --- a/tox.ini +++ b/tox.ini @@ -17,11 +17,10 @@ commands = pip install PyQt5==5.15.6 PyQt3D==5.15.5 PyQtChart==5.15.5 PyQtDataVisualization==5.15.5 PyQtNetworkAuth==5.15.5 PyQtPurchasing==5.15.5 PyQtWebEngine==5.15.5 pip freeze --all mypy --show-error-codes -p PyQt5-stubs - stubtest --allowlist {toxinidir}/{env:ALLOWLIST} --allowlist {toxinidir}/stubtest.allowlist.to_review --allowlist {toxinidir}/stubtest.allowlist.{env:OS_MARKER} PyQt5 + python {toxinidir}/stubtest_wrapper.py --allowlist {toxinidir}/{env:ALLOWLIST} --allowlist {toxinidir}/stubtest.allowlist.to_review --allowlist {toxinidir}/stubtest.allowlist.{env:OS_MARKER} PyQt5 pytest --capture=no --verbose {posargs} [pytest] addopts = --strict-markers testpaths = tests xfail_strict = true - From 28b84b8090f2029981d255d12099b60ebf04fffe Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Mon, 28 Nov 2022 11:33:39 -0500 Subject: [PATCH 5/9] Update setup.py --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 451f686..f826323 100644 --- a/setup.py +++ b/setup.py @@ -54,7 +54,7 @@ def find_version(*file_paths): "dev": [ "mypy==0.991; python_version >= '3.7'", # https://github.com/python/mypy/commit/dc118e293203863ab1007699b2cecf0f26ddfa22 - "mypy==0.980; python_version < '3.7'", + "mypy==0.971; python_version < '3.7'", "pytest", "pytest-xvfb", ], From 7f86f099b8777b261df4197bec466045086fa6c3 Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Mon, 28 Nov 2022 11:40:58 -0500 Subject: [PATCH 6/9] print when successfully monkey patched as well --- stubtest_wrapper.py | 1 + 1 file changed, 1 insertion(+) diff --git a/stubtest_wrapper.py b/stubtest_wrapper.py index 2a5027e..ace5c71 100644 --- a/stubtest_wrapper.py +++ b/stubtest_wrapper.py @@ -21,6 +21,7 @@ def maybe_monkey_patch() -> None: return mypy.stubtest._verify_final = noop_generator + print("mypy.stubtest._verify_final monkey patched to do nothing") return From 1b99db90de8077e98269ccddb2563044777df12c Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Mon, 28 Nov 2022 11:44:38 -0500 Subject: [PATCH 7/9] sys.stdout.flush() --- stubtest_wrapper.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/stubtest_wrapper.py b/stubtest_wrapper.py index ace5c71..8f5200c 100644 --- a/stubtest_wrapper.py +++ b/stubtest_wrapper.py @@ -28,6 +28,8 @@ def maybe_monkey_patch() -> None: def main() -> int: maybe_monkey_patch() + # make sure the messages get out since we're working around a segfault here + sys.stdout.flush() return mypy.stubtest.main() From ddd513cab954e8293215edec1964de6aad579daa Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Mon, 28 Nov 2022 11:45:40 -0500 Subject: [PATCH 8/9] faulthandler --- stubtest_wrapper.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/stubtest_wrapper.py b/stubtest_wrapper.py index 8f5200c..3cc79a6 100644 --- a/stubtest_wrapper.py +++ b/stubtest_wrapper.py @@ -1,5 +1,6 @@ # workaround for https://github.com/python/mypy/issues/14196 +import faulthandler import sys import typing @@ -30,6 +31,9 @@ def main() -> int: # make sure the messages get out since we're working around a segfault here sys.stdout.flush() + # in case we still get a segfault, try to report it + faulthandler.enable() + return mypy.stubtest.main() From 71f811103ff3b84b621a55efdab4b3b8f7cc2c64 Mon Sep 17 00:00:00 2001 From: Kyle Altendorf Date: Mon, 28 Nov 2022 12:27:48 -0500 Subject: [PATCH 9/9] it is... more complicated --- setup.py | 10 ++++++++-- stubtest_wrapper.py | 24 ++++++++++++++---------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/setup.py b/setup.py index f826323..2ebe986 100644 --- a/setup.py +++ b/setup.py @@ -52,9 +52,15 @@ def find_version(*file_paths): packages=["PyQt5-stubs"], extras_require={ "dev": [ + # 0.940 introduced class finality testing that segfaults on PyQt5 + # https://github.com/python/mypy/commit/080bb0e04e9d5c4d2513621d1fb62f1d61a573e9 + # https://www.riverbankcomputing.com/pipermail/pyqt/2022-November/045068.html + # >= 0.990 for monkey patchable class finality check function + # https://github.com/python/mypy/commit/55d757e4910a0ae73175a71f3c0f02caad53e059 "mypy==0.991; python_version >= '3.7'", - # https://github.com/python/mypy/commit/dc118e293203863ab1007699b2cecf0f26ddfa22 - "mypy==0.971; python_version < '3.7'", + # 0.981 dropped 3.6 support + # https://github.com/python/mypy/commit/dc118e293203863ab1007699b2cecf0f26ddfa22 + "mypy<0.940; python_version < '3.7'", "pytest", "pytest-xvfb", ], diff --git a/stubtest_wrapper.py b/stubtest_wrapper.py index 3cc79a6..3bf64d4 100644 --- a/stubtest_wrapper.py +++ b/stubtest_wrapper.py @@ -7,27 +7,31 @@ import mypy.stubtest +sentinel = object + + def noop_generator(*args, **kwargs) -> typing.Iterator[object]: return yield # make it a generator as the original is -def maybe_monkey_patch() -> None: - if not hasattr(mypy.stubtest, "_verify_final"): - print("mypy.stubtest._verify_final does not exist, skipping monkey patching") - return - - if not callable(mypy.stubtest._verify_final): - print("mypy.stubtest._verify_final is not a callable, skipping monkey patching") +def maybe_monkey_patch(object_: object, name: str, replacement: object) -> None: + attribute = getattr(object_, name, sentinel) + if attribute is sentinel: + print(f"{name} does not exist on {object_}, skipping monkey patching") return - mypy.stubtest._verify_final = noop_generator - print("mypy.stubtest._verify_final monkey patched to do nothing") + setattr(object_, name, replacement) + print(f"{name} on {object_} monkey patched by {replacement}") return def main() -> int: - maybe_monkey_patch() + maybe_monkey_patch( + object_=mypy.stubtest, + name="_verify_final", + replacement=noop_generator, + ) # make sure the messages get out since we're working around a segfault here sys.stdout.flush()