From 978c346e5d0d08a7944dd36e06482c5f8cf8b7fa Mon Sep 17 00:00:00 2001 From: David Lechner Date: Sun, 30 Jun 2024 14:33:49 -0500 Subject: [PATCH] pybricksdev.cli: initialize thread to MTA on Windows This fixes crashes like the following due to changes in Bleak that detects issues on Windows where callbacks won't be called because the pythoncom package sets the threading model to STA and there is no Windows message loop running. By initializing the thread to MTA before pythoncom is (lazy) imported, we avoid this issue. Issue: https://github.com/hbldh/bleak/discussions/1607#discussioncomment-9918382 ``` Traceback (most recent call last): File "C:\Users\david\work\pybricksdev\.venv\Scripts\\pybricksdev", line 6, in sys.exit(main()) ^^^^^^ File "C:\Users\david\work\pybricksdev\pybricksdev\cli\__init__.py", line 387, in main asyncio.run(subparsers.choices[args.tool].tool.run(args)) File "C:\Users\david\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 190, in run return runner.run(main) ^^^^^^^^^^^^^^^^ File "C:\Users\david\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 118, in run return self._loop.run_until_complete(task) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\david\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 650, in run_until_complete return future.result() ^^^^^^^^^^^^^^^ File "C:\Users\david\work\pybricksdev\pybricksdev\cli\lwp3\repl.py", line 134, in repl device = await BleakScanner.find_device_by_filter(match_lwp3_uuid) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\david\work\pybricksdev\.venv\Lib\site-packages\bleak\__init__.py", line 444, in find_device_by_filter async with cls(**kwargs) as scanner: File "C:\Users\david\work\pybricksdev\.venv\Lib\site-packages\bleak\__init__.py", line 158, in __aenter__ await self._backend.start() File "C:\Users\david\work\pybricksdev\.venv\Lib\site-packages\bleak\backends\winrt\scanner.py", line 225, in start await assert_mta() File "C:\Users\david\work\pybricksdev\.venv\Lib\site-packages\bleak\backends\winrt\util.py", line 149, in assert_mta raise BleakError( bleak.exc.BleakError: Thread is configured for Windows GUI but callbacks are not working. Suspect unwanted side effects from importing 'pythoncom'. ``` --- CHANGELOG.md | 4 ++++ pybricksdev/cli/__init__.py | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18d364c..d6cbc3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Use relative paths when compiling multi-file projects. +### Fixed +- Fixed `pybricksdev` BLE commands not working on Windows when `pythoncom` + package is present in environment. + ## [1.0.0-alpha.48] - 2024-05-04 ### Changed diff --git a/pybricksdev/cli/__init__.py b/pybricksdev/cli/__init__.py index 56c3ea6..5fb9df5 100644 --- a/pybricksdev/cli/__init__.py +++ b/pybricksdev/cli/__init__.py @@ -343,6 +343,15 @@ async def run(self, args: argparse.Namespace): def main(): """Runs ``pybricksdev`` command line interface.""" + if sys.platform == "win32": + # Hack around bad side-effects of pythoncom on Windows + try: + from bleak_winrt._winrt import MTA, init_apartment + except ImportError: + from winrt._winrt import MTA, init_apartment + + init_apartment(MTA) + # Provide main description and help. parser = argparse.ArgumentParser( prog=PROG_NAME,