diff --git a/setup.py b/setup.py index 579928e..625e6c8 100644 --- a/setup.py +++ b/setup.py @@ -51,7 +51,19 @@ def find_version(*file_paths): package_data={"PyQt5-stubs": ['*.pyi']}, packages=["PyQt5-stubs"], extras_require={ - "dev": ["mypy==0.930", "pytest", "pytest-xvfb"], + "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'", + # 0.981 dropped 3.6 support + # https://github.com/python/mypy/commit/dc118e293203863ab1007699b2cecf0f26ddfa22 + "mypy<0.940; python_version < '3.7'", + "pytest", + "pytest-xvfb", + ], }, classifiers=[ "Development Status :: 5 - Production/Stable", diff --git a/stubtest_wrapper.py b/stubtest_wrapper.py new file mode 100644 index 0000000..3bf64d4 --- /dev/null +++ b/stubtest_wrapper.py @@ -0,0 +1,44 @@ +# workaround for https://github.com/python/mypy/issues/14196 + +import faulthandler +import sys +import typing + +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(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 + + setattr(object_, name, replacement) + print(f"{name} on {object_} monkey patched by {replacement}") + return + + +def main() -> int: + 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() + # in case we still get a segfault, try to report it + faulthandler.enable() + + return mypy.stubtest.main() + + +sys.exit(main()) diff --git a/tox.ini b/tox.ini index fbf458c..f2ff773 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 -