fix(tests): use str-enum for mock ParseMode/ChatType to fix order-dependent failures - #33875
fix(tests): use str-enum for mock ParseMode/ChatType to fix order-dependent failures#33875liuhao1024 wants to merge 1 commit into
Conversation
…endent failures The _ensure_telegram_mock() helper in tests/gateway/conftest.py and 15 per-file copies set ParseMode.MARKDOWN_V2 = "MarkdownV2" as a plain string. When installed before the real python-telegram-bot package is imported, this poisons sys.modules for the entire pytest session. Tests asserting repr(parse_mode) or isinstance checks fail because the mock produces a plain string instead of the str-enum member. Fix: replace plain string assignments with proper str-enum classes (_ParseMode, _ChatType) whose repr() matches the real package. Also set enum references directly on the module object (mod.ParseMode, mod.ChatType) so that 'from telegram.constants import ChatType' resolves correctly. Fixes NousResearch#33079
|
The str-enum mock approach is the right call here. One thing to watch for: some test assertions in the codebase directly compare against the string value ("Markdown") rather than using the enum member. If a downstream assertion does , the str-enum will still match because resolves True thanks to the str mixin. But if anything does a type check (), it'll pass now since str-enum is both a str and an Enum. Should be compatible, just noting it. |
|
Good point about downstream assertions comparing against string values. I checked the test files that import If you spot any specific assertion that breaks, let me know and I'll add a targeted test. |
teknium1
left a comment
There was a problem hiding this comment.
Thanks for isolating the Telegram mock-shape issue. The central change targets a real current-main mismatch: tests/gateway/conftest.py:64-70 configures nested constants, while tests/gateway/conftest.py:91-98 registers the root mock as telegram.constants; the adapter imports directly from that module at plugins/platforms/telegram/adapter.py:169.
Problems
tests/e2e/conftest.py:14addsimport enumwithout using it or changing the E2E Telegram mock. That hunk does not affect ParseMode/ChatType behavior.
Suggested changes
- Drop the unused E2E import, or fully convert that fixture if E2E coverage needs the same import contract.
- During salvage, add a focused regression that imports
ParseModeandChatTypefromtelegram.constants; this directly guards the root-versus-nested mock path that the adapter uses.
Automated hermes-sweeper review.
|
|
||
| import asyncio | ||
| import sys | ||
| import enum |
There was a problem hiding this comment.
This import is unused: the diff does not change this fixture's Telegram mock. Please remove this hunk, or convert ParseMode/ChatType and expose them on telegram_mod if the E2E fixture needs the same direct-import contract.
|
Thanks @liuhao1024 — closing in favor of #68873, which fixes the same telegram-mock str-enum class at the poison source (the dm_topics unconditional divergent mock) with a single PTB-faithful _FakeEnumMember instead of 15 per-file patches. You diagnosed this class TWO MONTHS earlier — you are credited as the earliest diagnoser in the landing commit. The salvage of #68873 is in progress. |
The file-local telegram mock in test_dm_topics.py installed unconditionally (no __file__ guard), registered a separate string-valued telegram.constants module, and force-popped the adapter — poisoning the session for any later telegram test in the same process (assert 'MARKDOWN_V2' in "'MarkdownV2'"). Fix at the source: - conftest: _FakeEnumMember(str) with PTB-faithful str()==value and repr()==<ChatType.X: 'x'>, satisfying both repr assertions and the adapter's str(chat.type) normalization; the same object is bound to mod.ParseMode and mod.constants.ParseMode. - test_dm_topics.py: delete the divergent local mock installer; import the shared conftest one. - release.py: mailmap entry for the author. Verified: the 5-failure cluster repro (dm_topics + slash_confirm + approval_buttons + model_picker + network_reconnect + telegram_format in one process) goes 83/83 green (3x); full tests/gateway single-process run drops 10 -> 5 failed, the remainder being pre-existing discord order-dep failures out of scope here. Salvaged from #68873. Credit to @liuhao1024 for the earliest root-cause diagnosis of this str-enum mock class in PR #33875, two months earlier. Fixes the telegram-mock order-dependent flake cluster.
The file-local telegram mock in test_dm_topics.py installed unconditionally (no __file__ guard), registered a separate string-valued telegram.constants module, and force-popped the adapter — poisoning the session for any later telegram test in the same process (assert 'MARKDOWN_V2' in "'MarkdownV2'"). Fix at the source: - conftest: _FakeEnumMember(str) with PTB-faithful str()==value and repr()==<ChatType.X: 'x'>, satisfying both repr assertions and the adapter's str(chat.type) normalization; the same object is bound to mod.ParseMode and mod.constants.ParseMode. - test_dm_topics.py: delete the divergent local mock installer; import the shared conftest one. - release.py: mailmap entry for the author. Verified: the 5-failure cluster repro (dm_topics + slash_confirm + approval_buttons + model_picker + network_reconnect + telegram_format in one process) goes 83/83 green (3x); full tests/gateway single-process run drops 10 -> 5 failed, the remainder being pre-existing discord order-dep failures out of scope here. Salvaged from NousResearch#68873. Credit to @liuhao1024 for the earliest root-cause diagnosis of this str-enum mock class in PR NousResearch#33875, two months earlier. Fixes the telegram-mock order-dependent flake cluster.
The file-local telegram mock in test_dm_topics.py installed unconditionally (no __file__ guard), registered a separate string-valued telegram.constants module, and force-popped the adapter — poisoning the session for any later telegram test in the same process (assert 'MARKDOWN_V2' in "'MarkdownV2'"). Fix at the source: - conftest: _FakeEnumMember(str) with PTB-faithful str()==value and repr()==<ChatType.X: 'x'>, satisfying both repr assertions and the adapter's str(chat.type) normalization; the same object is bound to mod.ParseMode and mod.constants.ParseMode. - test_dm_topics.py: delete the divergent local mock installer; import the shared conftest one. - release.py: mailmap entry for the author. Verified: the 5-failure cluster repro (dm_topics + slash_confirm + approval_buttons + model_picker + network_reconnect + telegram_format in one process) goes 83/83 green (3x); full tests/gateway single-process run drops 10 -> 5 failed, the remainder being pre-existing discord order-dep failures out of scope here. Salvaged from NousResearch#68873. Credit to @liuhao1024 for the earliest root-cause diagnosis of this str-enum mock class in PR NousResearch#33875, two months earlier. Fixes the telegram-mock order-dependent flake cluster.
The file-local telegram mock in test_dm_topics.py installed unconditionally (no __file__ guard), registered a separate string-valued telegram.constants module, and force-popped the adapter — poisoning the session for any later telegram test in the same process (assert 'MARKDOWN_V2' in "'MarkdownV2'"). Fix at the source: - conftest: _FakeEnumMember(str) with PTB-faithful str()==value and repr()==<ChatType.X: 'x'>, satisfying both repr assertions and the adapter's str(chat.type) normalization; the same object is bound to mod.ParseMode and mod.constants.ParseMode. - test_dm_topics.py: delete the divergent local mock installer; import the shared conftest one. - release.py: mailmap entry for the author. Verified: the 5-failure cluster repro (dm_topics + slash_confirm + approval_buttons + model_picker + network_reconnect + telegram_format in one process) goes 83/83 green (3x); full tests/gateway single-process run drops 10 -> 5 failed, the remainder being pre-existing discord order-dep failures out of scope here. Salvaged from NousResearch#68873. Credit to @liuhao1024 for the earliest root-cause diagnosis of this str-enum mock class in PR NousResearch#33875, two months earlier. Fixes the telegram-mock order-dependent flake cluster.
What does this PR do?
The
_ensure_telegram_mock()helper intests/gateway/conftest.pyand 15 per-file copies setParseMode.MARKDOWN_V2 = "MarkdownV2"as a plain string. When installed before the realpython-telegram-botpackage is imported, this poisonssys.modulesfor the entire pytest session. Tests assertingrepr(parse_mode)fail because the mock produces'MarkdownV2'(plain string repr) instead ofParseMode.MARKDOWN_V2(enum repr containing"MARKDOWN_V2").6 tests fail in combined
pytest tests/gateway/ -k telegrambut pass individually:test_telegram_approval_buttons.py::test_send_update_prompt_escapes_dynamic_prompttest_telegram_approval_buttons.py::test_approval_callback_escapes_dynamic_user_nametest_telegram_model_picker.py::test_send_model_picker_escapes_dynamic_provider_labeltest_telegram_model_picker.py::test_back_button_escapes_dynamic_provider_labeltest_telegram_model_picker.py::test_model_selected_edits_message_on_successtest_telegram_slash_confirm.py::test_uses_markdown_v2_and_escapes_special_charsRelated Issue
Fixes #33079
Type of Change
Changes Made
How to Test
pytest tests/ -q— all tests should passChecklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests passDocumentation & Housekeeping
docs/, docstrings) — or N/Acli-config.yaml.exampleif I added/changed config keys — or N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture and workflows — or N/ACode Intelligence
tests/gateway/conftest.py:_ensure_telegram_mockand 15 per-file copiessys.modulesmock poisoning is a common pytest anti-pattern;str-enum ensures type-compatible comparisonsChecklist