fix(deps): make uamqp optional on ARM macOS to fix installation failure#18
fix(deps): make uamqp optional on ARM macOS to fix installation failure#18marcodalessandro wants to merge 11 commits intoAzure:mainfrom
Conversation
uamqp fails to build on Apple Silicon due to stricter clang type checking. Exclude it from install_requires on ARM macOS via PEP 508 marker while keeping it for Windows, Linux, and Intel Mac. Add [amqp] extra for opt-in. Gracefully handle missing uamqp at runtime so all non-C2D functionality works without it.
There was a problem hiding this comment.
Pull request overview
Makes uamqp optional on ARM macOS (Apple Silicon) to prevent installation failures while preserving non-AMQP SDK functionality, and provides clearer runtime errors + docs for opting into C2D AMQP messaging.
Changes:
- Adds runtime handling when
uamqpis missing (fallbackTransportType, graceful init, and explicit ImportErrors for C2D usage). - Updates packaging to exclude
uamqpon ARM macOS by default and introduces an[amqp]extra. - Adds/updates tests and README to validate and document the new behavior.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_no_uamqp.py | New tests to validate SDK behavior when uamqp is absent. |
| tests/test_iothub_amqp_client.py | Skips AMQP tests when uamqp is not installed. |
| src/azure/iot/hub/iothub_registry_manager.py | Adds fallback TransportType, avoids failing construction without uamqp, and errors clearly on send_c2d_message. |
| src/azure/iot/hub/iothub_amqp_client.py | Makes uamqp import optional; raises clear ImportError when AMQP paths are used without it. |
| src/azure/iot/hub/constant.py | Bumps package version to 2.8.0. |
| setup.py | Uses PEP 508 marker to exclude uamqp on ARM macOS and adds [amqp] extra. |
| README.md | Documents platform behavior, opt-in install, and C2D AMQP usage. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Replace bare except ImportError with explicit HAS_UAMQP check - Use IntEnum for fallback TransportType for better API compatibility - Remove unused imports in test_no_uamqp.py - Strengthen test_delete_device assertion with exact call args
|
All review feedback has been addressed in commit d038f75: 1. Silent 2. Use 3. README markdown table double pipes 4-5. Unused imports and standalone string in 6. All 185 tests pass. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
six is a Python 2 compatibility library that is not reliably available as a transitive dependency on all Python versions, causing CI failures.
The existing test file imported TransportType directly from uamqp, which fails on ARM macOS where uamqp is not installed. Import from the registry manager module which has a fallback enum.
- Deduplicate ImportError message using shared _UAMQP_MISSING_ERROR constant
- Fix mutable default argument properties={} in send_c2d_message
- Improve fallback IntEnum test to exercise actual runtime fallback via reload
|
Second round of review feedback addressed in commit f2e5db3: 1. Duplicated ImportError message (iothub_registry_manager.py:962) 2. Non-ASCII characters need encoding cookie (test_no_uamqp.py:44) 3. Fallback IntEnum test should exercise actual runtime fallback (test_no_uamqp.py:217) 4. Mutable default argument All 185 tests pass locally. CI should confirm shortly. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 10 changed files in this pull request and generated 6 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Revert six.moves.urllib back to maintain Python 2 compatibility declared in setup.py metadata. Add six as explicit install_requires since it is used directly. Trim CI matrix to match classifiers (3.9-3.10).
|
Third round of review feedback addressed: Already resolved by previous commits:
Resolved in this round:
Not changing (by design):
All 185 tests pass. CI green on all 6 matrix jobs (3 OS x 2 Python versions). |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
tests/test_no_uamqp.py
Outdated
| assert FallbackTransportType.Amqp == 1 | ||
| assert FallbackTransportType.AmqpOverWebsocket == 3 | ||
|
|
||
| # Restore original module state |
There was a problem hiding this comment.
In this test, the final importlib.reload(registry_module) happens while builtins.__import__ is still monkeypatched to raise for uamqp, so the module can remain in the fallback (no-uamqp) state for the rest of the test session. Restore builtins.__import__ (or stop the monkeypatch) before the final reload, or avoid reloading here and instead rely on pytest’s teardown to restore the import hook.
| # Restore original module state | |
| # Restore original module state: first restore __import__, then reload. | |
| monkeypatch.setattr(builtins, "__import__", real_import) |
| # ────────────────────────────────────────────────────────────────────── | ||
| # Fixtures | ||
| # ────────────────────────────────────────────────────────────────────── | ||
|
|
||
|
|
There was a problem hiding this comment.
This new test module includes non-ASCII characters (e.g., box-drawing separators / em dashes) and imports the builtins module directly. If the project’s stated Python 2.7 support is still intended (see setup.py classifiers / python_requires), this file will fail to parse/import on Python 2.7. Consider using ASCII-only separators and importing builtins via six.moves.builtins (or a small compatibility shim) to keep the test suite importable under 2.7.
| | Platform | C2D messaging support | Notes | | ||
| |---|---|---| | ||
| | Windows | Included automatically | `uamqp` is installed as part of `pip install azure-iot-hub` | | ||
| | Linux | Included automatically | `uamqp` is installed as part of `pip install azure-iot-hub` | | ||
| | macOS (Intel) | Included automatically | `uamqp` is installed as part of `pip install azure-iot-hub` | | ||
| | macOS (Apple Silicon / ARM) | **Not installed automatically** | Recent versions of Xcode/clang enforce stricter C type checking that breaks the `uamqp` build. See below. | | ||
|
|
There was a problem hiding this comment.
The Markdown table under “C2D messaging and uamqp” uses double leading pipes (||) in the separator and data rows, which breaks table rendering in common Markdown parsers. Use single | to start each row (e.g., |---|---|---| and | Windows | ... | ... |).
|
Fourth round of review feedback addressed in commit 28424d6: Fixed:
Not changing (same reasons as before):
|
Co-Authored-By: Claude <noreply@anthropic.com>
This pull request adds robust support for environments where the
uamqpdependency (required for AMQP-based Cloud-to-Device (C2D) messaging) cannot be installed, specifically ARM macOS (Apple Silicon). It makesuamqpoptional on those platforms, provides clear error handling and installation instructions when C2D messaging is attempted without it, and documents the new behavior in the README. Comprehensive tests are also added to verify correct SDK behavior whenuamqpis absent. Other SDK features (device/module CRUD, twin operations, etc.) remain fully functional withoutuamqp.Dependency and Platform Support
setup.pyto makeuamqpan optional dependency on ARM macOS (Apple Silicon), with an opt-inamqpextra for users who can build it in their environment.2.8.0to reflect these changes.Error Handling and Fallbacks
ImportErrorwith installation instructions when C2D messaging is used withoutuamqp. AMQP client classes also raise on construction ifuamqpis missing. [1] [2] [3] [4] [5] [6]TransportTypeenum for use whenuamqpis not installed, ensuring API compatibility.Documentation Updates
README.mdto document the new installation workflow, platform-specific behavior, and how to opt in to C2D messaging on ARM macOS. Also clarified which SDK features requireuamqpand which do not.Testing
tests/test_no_uamqp.py) that simulates the absence ofuamqpand verifies that REST operations work, C2D messaging fails with a clear error, and fallback behaviors are correct.uamqpis not available.uamqp fails to build on Apple Silicon due to stricter clang type checking. Exclude it from install_requires on ARM macOS via PEP 508 marker while keeping it for Windows, Linux, and Intel Mac. Add [amqp] extra for opt-in. Gracefully handle missing uamqp at runtime so all non-C2D functionality works without it.