fix(telegram): attach polling instrumentation without an instance attribute - #64639
Closed
roosy12 wants to merge 1 commit into
Closed
fix(telegram): attach polling instrumentation without an instance attribute#64639roosy12 wants to merge 1 commit into
roosy12 wants to merge 1 commit into
Conversation
…ribute
HTTPXRequest declares __slots__ (python-telegram-bot >= 22), so
_instrument_polling_request()'s `request.do_request = _do_request` raises
AttributeError: 'HTTPXRequest' object attribute 'do_request' is read-only
and Telegram startup aborts. The adapter cannot connect at all.
Attach the wrapper by rebinding request.__class__ to a subclass that overrides
do_request instead. A subclass with empty __slots__ has the same instance
layout, so __class__ assignment is legal and creates no per-instance attribute.
The wrapper must not simply be skipped when it fails to attach: the polling
progress verifier consumes what _record_polling_progress() records, so a no-op
wrapper makes healthy polling look stalled and drops the adapter into a
reconnect loop ("getUpdates made no progress before verifier deadline").
Add a regression test against the real HTTPXRequest. The existing request
doubles subclass BaseRequest without __slots__, so they acquire a __dict__ and
accept the assignment — which is why the suite did not catch this.
Fixes NousResearch#64566
Fixes NousResearch#64482
Collaborator
Duplicate of #64506 — same fix for the same regression (merged #64381's |
This was referenced Aug 3, 2026
Closed
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.
Problem
Telegram cannot connect at all on v0.18.2. The adapter aborts on startup with:
Reported in #64566 and #64482.
Root cause
_instrument_polling_request()attaches its progress-tracking wrapper by assigning the attribute on the instance:HTTPXRequestdeclares__slots__(python-telegram-bot >= 22), so the instance has no__dict__and the assignment raisesAttributeError.Fix
Attach the wrapper by rebinding
request.__class__to a subclass that overridesdo_request. A subclass with empty__slots__has the same instance layout, so__class__assignment is legal and creates no per-instance attribute. The instrumentation itself is unchanged.Why the wrapper must not simply be skipped
The obvious fix — wrapping the assignment in
try/except AttributeErrorand moving on — is wrong, and I tried it first. The polling-progress verifier consumes what_record_polling_progress()records. With a no-op wrapper, healthy polling looks stalled and the adapter drops into a reconnect loop:So the wrapper has to actually attach, not merely fail quietly.
Testing
Added a regression test against the real
HTTPXRequest:mainit fails with the exact production error (AttributeError ... is read-onlyatadapter.py:1999).tests/test_telegram_polling_progress_ptb.pygoes from 7 passing to 8 passing when run on its own.The existing request doubles subclass
BaseRequestwithout__slots__, so they acquire a__dict__and happily accept the assignment. That is why the suite never caught this — the doubles do not model the constraint that production hits.Verified against a live bot: the gateway now connects, holds the
getUpdateslong-poll, and replies to messages.Pre-existing issue noticed, unrelated to this change
Every test in
tests/test_telegram_polling_progress_ptb.pyfails when the file runs aftertests/gateway/test_telegram_*.pyin the same pytest session — this also happens on unmodifiedmain(baseline: 7 failed / 68 passed; with this change: 8 failed / 68 passed, the extra failure being the new test succumbing to the same ordering issue). Run on its own the file is green. Flagging it as a separate test-isolation problem so it isn't mistaken for a regression from this PR.Fixes #64566
Fixes #64482
🤖 Generated with Claude Code