-
Notifications
You must be signed in to change notification settings - Fork 373
fix: support Python 3.14 compatibility #6419
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| from unittest import TestCase | ||
|
|
||
| from press.press.doctype.deploy_candidate.docker_output_parsers import get_command | ||
|
|
||
|
|
||
| class TestDockerOutputParsers(TestCase): | ||
| def test_get_command_strips_run_flags_and_stage_marker(self): | ||
| name = "RUN --mount=type=cache,target=/root/.cache pip install -e apps/frappe `#stage-install-frappe`" | ||
|
|
||
| self.assertEqual(get_command(name), "pip install -e apps/frappe") | ||
|
|
||
| def test_get_command_normalizes_line_folds(self): | ||
| name = "RUN apt-get update \\\n && apt-get install -y curl \\\n && rm -rf /var/lib/apt/lists/* `#stage-setup-apt`" | ||
|
|
||
| self.assertEqual( | ||
| get_command(name), | ||
| "apt-get update\n&& apt-get install -y curl\n&& rm -rf /var/lib/apt/lists/*", | ||
| ) | ||
|
|
||
| def test_get_command_keeps_json_form_run(self): | ||
| name = 'RUN ["python", "-m", "compileall", "apps"] `#stage-compile-assets`' | ||
|
|
||
| self.assertEqual(get_command(name), '["python", "-m", "compileall", "apps"]') | ||
|
|
||
| def test_get_command_preserves_quoted_arguments(self): | ||
| name = 'RUN echo "hello world" `#stage-print-message`' | ||
|
|
||
| self.assertEqual(get_command(name), 'echo "hello world"') |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,8 +2,11 @@ | |
| # For license information, please see license.txt | ||
|
|
||
|
|
||
| import asyncio | ||
|
|
||
| import frappe | ||
| import telegram | ||
| from telegram.constants import MessageLimit, ParseMode | ||
|
|
||
| from press.utils import log_error | ||
|
|
||
|
|
@@ -30,14 +33,13 @@ def send(self, message, html=False, reraise=False): | |
| if not message: | ||
| return None | ||
| try: | ||
| text = message[: telegram.MAX_MESSAGE_LENGTH] | ||
| text = message[: MessageLimit.MAX_TEXT_LENGTH] | ||
| parse_mode = self._get_parse_mode(html) | ||
| return self.bot.send_message( | ||
| chat_id=self.chat_id, | ||
| text=text, | ||
| parse_mode=parse_mode, | ||
| message_thread_id=self.topic_id, | ||
| timeout=3, | ||
| return asyncio.run( | ||
| self._send_message( | ||
| text=text, | ||
| parse_mode=parse_mode, | ||
| ) | ||
| ) | ||
| except Exception: | ||
| if reraise: | ||
|
|
@@ -52,8 +54,30 @@ def send(self, message, html=False, reraise=False): | |
|
|
||
| def _get_parse_mode(self, html): | ||
| if html: | ||
| return telegram.ParseMode.HTML | ||
| return telegram.ParseMode.MARKDOWN | ||
| return ParseMode.HTML | ||
| return ParseMode.MARKDOWN | ||
|
|
||
| async def _send_message(self, text, parse_mode): | ||
| bot = self.bot | ||
| async with bot: | ||
| return await bot.send_message( | ||
| chat_id=self.chat_id, | ||
| text=text, | ||
| parse_mode=parse_mode, | ||
| message_thread_id=self.topic_id, | ||
| read_timeout=3, | ||
| write_timeout=3, | ||
| connect_timeout=3, | ||
| pool_timeout=3, | ||
| ) | ||
|
|
||
| def _get_bot_username(self): | ||
| return asyncio.run(self._get_bot_username_async()) | ||
|
|
||
| async def _get_bot_username_async(self): | ||
| bot = self.bot | ||
| async with bot: | ||
| return bot.username | ||
|
Comment on lines
+74
to
+80
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Prompt To Fix With AIThis is a comment left during a code review.
Path: press/telegram_utils.py
Line: 74-80
Comment:
**`_get_bot_username()` makes a live API call on every `respond()` invocation**
`respond()` now calls `_get_bot_username()` for every incoming Telegram message, which creates a fresh `Bot` instance, calls `asyncio.run()`, and performs a full HTTP round-trip to Telegram just to obtain the bot's username — a value that never changes at runtime. In the old v13 API this was effectively free. A simple fix is to cache the username as an instance attribute on first use (e.g., `self._username`) so only the first message incurs the network call.
How can I resolve this? If you propose a fix, please make it concise. |
||
|
|
||
| @property | ||
| def bot(self): | ||
|
|
@@ -82,7 +106,7 @@ def respond(self, message): | |
|
|
||
| mention = text[begin:end] | ||
| # Only respond to messages mentioning the bot | ||
| if mention != f"@{self.bot.username}": | ||
| if mention != f"@{self._get_bot_username()}": | ||
| return | ||
|
|
||
| command = text.replace(mention, "") | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shlex.joinre-encodes the command, breaking downstream splitting_get_run_commandcallsshlex.split(which strips quotes and consumes backslash-newline continuations) and thenshlex.join(which re-quotes tokens with single quotes). This means: (1)`#stage-xxx`markers get re-quoted as'#stage-xxx', soget_command'ssplit("#stage-")no longer matches them correctly; (2) backslash-newline line folds are consumed by shlex, soget_command's\\nsplit no longer works; (3)"hello world"(double-quoted) becomes'hello world'` (single-quoted) in the output.Tests 1, 2, and 4 (
test_get_command_strips_run_flags_and_stage_marker,test_get_command_normalizes_line_folds,test_get_command_preserves_quoted_arguments) will fail for these reasons. The fix is to avoid re-encoding: locate the index in the originalvaluestring where non-flag content begins, and slicevaluedirectly rather than reconstructing viashlex.join.Prompt To Fix With AI