fix(servicebus): annotate async auto_lock_renewer with aio AutoLockRenewer (#47948)#47998
Merged
EldertGrootenboer merged 4 commits intoJul 10, 2026
Merged
Conversation
…newer The async ServiceBusClient receiver factory methods (get_queue_receiver, get_subscription_receiver) and the async ServiceBusReceiver annotated the auto_lock_renewer keyword with the synchronous AutoLockRenewer (azure.servicebus._common.auto_lock_renewer), contradicting their own docstrings and the runtime-correct behavior, which require the async azure.servicebus.aio.AutoLockRenewer. Static type checkers (pyright/mypy/ty) rejected the documented usage, forcing a cast() or suppression at every async call site. The sync renewer is thread-based and cannot drive an async receiver, so the annotated class was genuinely incompatible. Repoint the annotation to the async AutoLockRenewer via a TYPE_CHECKING import + string forward-ref in both files, and add a type-checked async sample (renew_lock_via_receiver_auto_lock_renewer_keyword) as a static regression guard so the repo's type_check_samples gate now covers the path. Fixes #47948
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes a type-annotation mismatch in the async Service Bus client/receiver APIs so that auto_lock_renewer is typed as the async azure.servicebus.aio.AutoLockRenewer (matching docs and runtime behavior), and adds an async sample to ensure the keyword argument path is exercised by static type checking.
Changes:
- Updated
azure.servicebus.aioreceiver factory method annotations to reference the asyncAutoLockRenewerviaTYPE_CHECKING+ forward refs. - Updated async
ServiceBusReceivertyping import to the async renewer type. - Added an async sample that passes
auto_lock_renewer=to the receiver factory as a static regression guard, and documented the new sample scenario.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_client_async.py | Switches auto_lock_renewer annotations to "AutoLockRenewer" with a TYPE_CHECKING import to avoid runtime circular imports. |
| sdk/servicebus/azure-servicebus/azure/servicebus/aio/_servicebus_receiver_async.py | Updates the type-checking import of AutoLockRenewer to the async implementation. |
| sdk/servicebus/azure-servicebus/samples/async_samples/auto_lock_renew_async.py | Adds a new async sample function that passes the renewer via auto_lock_renewer= to exercise static typing. |
| sdk/servicebus/azure-servicebus/CHANGELOG.md | Records the bugfix in the Unreleased section. |
…eption-safe shutdown
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix async
auto_lock_renewerannotation (sync → aioAutoLockRenewer)Fixes #47948
Problem
The async
azure.servicebus.aioreceiver factory methods —ServiceBusClient.get_queue_receiver,ServiceBusClient.get_subscription_receiver,and the async
ServiceBusReceiverconstructor — annotated theauto_lock_renewerkeyword with the synchronous
AutoLockRenewer(
azure.servicebus._common.auto_lock_renewer), contradicting their own docstringsand the runtime-correct behavior, which require the async
azure.servicebus.aio.AutoLockRenewer.Static type checkers (pyright / mypy / ty) therefore reject the documented,
runtime-correct usage, forcing a
cast()or a suppression at every async callsite. The mismatch is not merely cosmetic: the sync renewer's renewal loop is
thread-based and calls
renew_lock()synchronously, whereas the asyncreceiver/session
renew_lockis a coroutine — so the annotated class cannotdrive an async receiver at all.
Fix
auto_lock_renewerannotation to the asyncAutoLockRenewerinboth
aio/_servicebus_client_async.pyandaio/_servicebus_receiver_async.py.TYPE_CHECKING(it was only ever used forthe annotation — the value is passed through as an instance), with the two
annotations becoming string forward-refs. This mirrors the receiver's existing
pattern and avoids a circular import (
_async_auto_lock_renewerimportsServiceBusReceiverat runtime).renew_lock_via_receiver_auto_lock_renewer_keyword, that passes the renewer viathe
auto_lock_renewer=keyword. The repo'stype_check_samplesgate nowcovers this path (previously no sample exercised the keyword), so a regression
is caught statically.
Verification
mypyover the reporter's snippet and over the new sample: errors againstthe pre-fix source (arg-type on the
auto_lock_renewer=argument) and passesagainst the fixed source.
azure.servicebus.aiois unaffected (annotations are stringforward-refs; the moved import is
TYPE_CHECKING-only).Notes
aio-only correction.~azure.servicebus.aio.AutoLockRenewer; thisaligns the annotation to the existing documentation.