Skip to content

Commit

Permalink
pybricksdev.cli: initialize thread to MTA on Windows
Browse files Browse the repository at this point in the history
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: hbldh/bleak#1607 (comment)

```
Traceback (most recent call last):
  File "C:\Users\david\work\pybricksdev\.venv\Scripts\\pybricksdev", line 6, in <module>
    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'.
```
  • Loading branch information
dlech committed Jun 30, 2024
1 parent 942f30b commit 978c346
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions pybricksdev/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 978c346

Please sign in to comment.