chore(deps): Update actions/setup-python action to v7 #13

Open
Renovate wants to merge 1 commit from renovate/actions-setup-python-7.x into master
Collaborator

This PR contains the following updates:

Package Type Update Change
actions/setup-python action major v6v7

Release Notes

actions/setup-python (actions/setup-python)

v7.0.0

Compare Source

What's Changed

Enhancements
Bug Fix
Dependency Upgrade

New Contributors

Full Changelog: https://github.com/actions/setup-python/compare/v6...v7.0.0

v7

Compare Source


Configuration

📅 Schedule: (in timezone Europe/Berlin)

  • Branch creation
    • "before 6am on monday"
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR has been generated by Mend Renovate CLI.

This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [actions/setup-python](https://github.com/actions/setup-python) | action | major | `v6` → `v7` | --- ### Release Notes <details> <summary>actions/setup-python (actions/setup-python)</summary> ### [`v7.0.0`](https://github.com/actions/setup-python/releases/tag/v7.0.0) [Compare Source](https://github.com/actions/setup-python/compare/v7.0.0...v7.0.0) #### What's Changed ##### Enhancements - Migrate to ESM and upgrade dependencies by [@&#8203;priyagupta108](https://github.com/priyagupta108) in [#&#8203;1330](https://github.com/actions/setup-python/pull/1330) - Pin SHA commits and update docs with latest versions by [@&#8203;HarithaVattikuti](https://github.com/HarithaVattikuti) in [#&#8203;1338](https://github.com/actions/setup-python/pull/1338) - Remove the pip-install input by [@&#8203;gowridurgad](https://github.com/gowridurgad) in [#&#8203;1336](https://github.com/actions/setup-python/pull/1336) ##### Bug Fix - Fix to Classify stderr warning messages as warnings instead of errors in annotations by [@&#8203;lmvysakh](https://github.com/lmvysakh) in [#&#8203;1335](https://github.com/actions/setup-python/pull/1335) - Validate and retry manifest fetch to prevent silent failures by [@&#8203;priyagupta108](https://github.com/priyagupta108) in [#&#8203;1332](https://github.com/actions/setup-python/pull/1332) ##### Dependency Upgrade - Bump certifi from 2020.6.20 to 2024.7.4 in /**tests**/data by [@&#8203;dependabot](https://github.com/dependabot) in [#&#8203;1328](https://github.com/actions/setup-python/pull/1328) - Remove EOL Python versions and Bumps numpy text fixture by [@&#8203;priya-kinthali](https://github.com/priya-kinthali) in [#&#8203;1333](https://github.com/actions/setup-python/pull/1333) - Upgrade [@&#8203;actions/cache](https://github.com/actions/cache) to 6.2.0 by [@&#8203;philip-gai](https://github.com/philip-gai) in [#&#8203;1337](https://github.com/actions/setup-python/pull/1337) #### New Contributors - [@&#8203;lmvysakh](https://github.com/lmvysakh) made their first contribution in [#&#8203;1335](https://github.com/actions/setup-python/pull/1335) - [@&#8203;philip-gai](https://github.com/philip-gai) made their first contribution in [#&#8203;1337](https://github.com/actions/setup-python/pull/1337) **Full Changelog**: <https://github.com/actions/setup-python/compare/v6...v7.0.0> ### [`v7`](https://github.com/actions/setup-python/compare/v6.3.0...v7.0.0) [Compare Source](https://github.com/actions/setup-python/compare/v6.3.0...v7.0.0) </details> --- ### Configuration 📅 **Schedule**: (in timezone Europe/Berlin) - Branch creation - "before 6am on monday" - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate CLI](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC43LjIiLCJ1cGRhdGVkSW5WZXIiOiI0NC4yOS41IiwidGFyZ2V0QnJhbmNoIjoibWFzdGVyIiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyIsInJlbm92YXRlIl19-->
chore(deps): Update actions/setup-python action to v7
Some checks failed
PR Tests / test (pull_request) Failing after 31s
fe169052da

CI Results

Check Status
Ruff
Pylint (9.93/10)
Config
Imports
Ruff output
I001 [*] Import block is un-sorted or un-formatted
  --> src/func/twitch.py:2:1
   |
 1 |   """Twitch API client: token management, user ID lookup, stream status."""
 2 | / import asyncio
 3 | | import time
 4 | | import logging
 5 | | from typing import Dict, Optional
 6 | |
 7 | | import aiohttp
 8 | |
 9 | | from .models import StreamInfo
   | |______________________________^
10 |
11 |   log = logging.getLogger(__name__)
   |
help: Organize imports
  |
2 | import asyncio
3 + import logging
4 | import time
  - import logging
5 | from typing import Dict, Optional
  |

UP035 `typing.Dict` is deprecated, use `dict` instead
 --> src/func/twitch.py:5:1
  |
3 | import time
4 | import logging
5 | from typing import Dict, Optional
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6 |
7 | import aiohttp
  |

UP045 [*] Use `X | None` for type annotations
  --> src/func/twitch.py:24:23
   |
22 |         self.client_id = client_id
23 |         self.client_secret = client_secret
24 |         self.session: Optional[aiohttp.ClientSession] = None
   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
25 |         self._token: Optional[str] = None
26 |         self._token_expires: float = 0
   |
help: Convert to `X | None`
   |
23 |         self.client_secret = client_secret
   -         self.session: Optional[aiohttp.ClientSession] = None
24 +         self.session: aiohttp.ClientSession | None = None
25 |         self._token: Optional[str] = None
   |

UP045 [*] Use `X | None` for type annotations
  --> src/func/twitch.py:25:22
   |
23 |         self.client_secret = client_secret
24 |         self.session: Optional[aiohttp.ClientSession] = None
25 |         self._token: Optional[str] = None
   |                      ^^^^^^^^^^^^^
26 |         self._token_expires: float = 0
   |
help: Convert to `X | None`
   |
24 |         self.session: Optional[aiohttp.ClientSession] = None
   -         self._token: Optional[str] = None
25 +         self._token: str | None = None
26 |         self._token_expires: float = 0
   |

UP006 [*] Use `dict` instead of `Dict` for type annotation
  --> src/func/twitch.py:80:45
   |
78 |             raise TwitchAPIError(f"Twitch API error: HTTP {r.status} for {url}")
79 |
80 |     async def fetch_user_ids(self, streams: Dict[str, StreamInfo]) -> None:
   |                                             ^^^^
81 |         """Resolve Twitch login names to user IDs and store them in each StreamInfo."""
82 |         await self.ensure_token()
   |
help: Replace with `dict`
   |
79 |
   -     async def fetch_user_ids(self, streams: Dict[str, StreamInfo]) -> None:
80 +     async def fetch_user_ids(self, streams: dict[str, StreamInfo]) -> None:
81 |         """Resolve Twitch login names to user IDs and store them in each StreamInfo."""
   |

UP006 [*] Use `dict` instead of `Dict` for type annotation
  --> src/func/twitch.py:90:49
   |
88 |                 log.debug("User ID for %s: %s", user["login"], user["id"])
89 |
90 |     async def fetch_live_streams(self, streams: Dict[str, StreamInfo]) -> Dict[str, dict]:
   |                                                 ^^^^
91 |         """Return a dict of currently live streams keyed by login name."""
92 |         await self.ensure_token()
   |
help: Replace with `dict`
   |
89 |
   -     async def fetch_live_streams(self, streams: Dict[str, StreamInfo]) -> Dict[str, dict]:
90 +     async def fetch_live_streams(self, streams: dict[str, StreamInfo]) -> Dict[str, dict]:
91 |         """Return a dict of currently live streams keyed by login name."""
   |

UP006 [*] Use `dict` instead of `Dict` for type annotation
  --> src/func/twitch.py:90:75
   |
88 |                 log.debug("User ID for %s: %s", user["login"], user["id"])
89 |
90 |     async def fetch_live_streams(self, streams: Dict[str, StreamInfo]) -> Dict[str, dict]:
   |                                                                           ^^^^
91 |         """Return a dict of currently live streams keyed by login name."""
92 |         await self.ensure_token()
   |
help: Replace with `dict`
   |
89 |
   -     async def fetch_live_streams(self, streams: Dict[str, StreamInfo]) -> Dict[str, dict]:
90 +     async def fetch_live_streams(self, streams: Dict[str, StreamInfo]) -> dict[str, dict]:
91 |         """Return a dict of currently live streams keyed by login name."""
   |

I001 [*] Import block is un-sorted or un-formatted
  --> src/func/watcher.py:2:1
   |
 1 |   """Main orchestrator: polls Twitch and dispatches Discord webhook notifications."""
 2 | / import asyncio
 3 | | import logging
 4 | | import queue
 5 | | import random
 6 | | from datetime import datetime, timedelta
 7 | | from typing import Dict, Optional
 8 | | from zoneinfo import ZoneInfo
 9 | | import configparser
10 | |
11 | | import aiohttp
12 | | import ntplib
13 | |
14 | | from .models import StreamInfo
15 | | from .twitch import TwitchClient, TwitchAPIError
16 | | from .webhook import WebhookSender
   | |__________________________________^
17 |
18 |   log = logging.getLogger(__name__)
   |
help: Organize imports
   |
2  | import asyncio
3  + import configparser
4  | import logging
--------------------------------------------------------------------------------
9  | from zoneinfo import ZoneInfo
   - import configparser
10 |
--------------------------------------------------------------------------------
14 | from .models import StreamInfo
   - from .twitch import TwitchClient, TwitchAPIError
15 + from .twitch import TwitchAPIError, TwitchClient
16 | from .webhook import WebhookSender
   |

UP035 `typing.Dict` is deprecated, use `dict` instead
 --> src/func/watcher.py:7:1
  |
5 | import random
6 | from datetime import datetime, timedelta
7 | from typing import Dict, Optional
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8 | from zoneinfo import ZoneInfo
9 | import configparser
  |

UP045 [*] Use `X | None` for type annotations
  --> src/func/watcher.py:28:70
   |
26 |     """Watches a set of Twitch streams and posts live notifications via Discord webhooks."""
27 |
28 |     def __init__(self, config: configparser.ConfigParser, log_queue: Optional[queue.Queue] = None):
   |                                                                      ^^^^^^^^^^^^^^^^^^^^^
29 |         dc = config["DISCORD"]
30 |         tw = config["TWITCH"]
   |
help: Convert to `X | None`
   |
27 |
   -     def __init__(self, config: configparser.ConfigParser, log_queue: Optional[queue.Queue] = None):
28 +     def __init__(self, config: configparser.ConfigParser, log_queue: queue.Queue | None = None):
29 |         dc = config["DISCORD"]
   |

UP006 [*] Use `dict` instead of `Dict` for type annotation
  --> src/func/watcher.py:50:23
   |
48 |         )
49 |
50 |         self.streams: Dict[str, StreamInfo] = {
   |                       ^^^^
51 |             name: StreamInfo(name=name)
52 |             for raw in tw["streams"].split(",")
   |
help: Replace with `dict`
   |
49 |
   -         self.streams: Dict[str, StreamInfo] = {
50 +         self.streams: dict[str, StreamInfo] = {
51 |             name: StreamInfo(name=name)
   |

BLE001 Do not catch blind exception: `Exception`
  --> src/func/watcher.py:78:28
   |
76 |                     except aiohttp.ClientError as e:
77 |                         log.error("Network error: %s", e)
78 |                     except Exception as e:  # pylint: disable=broad-exception-caught
   |                            ^^^^^^^^^
79 |                         log.error("Unexpected tick error: %s", e)
80 |                     await asyncio.sleep(self.poll_interval)
   |

BLE001 Do not catch blind exception: `Exception`
   --> src/func/watcher.py:115:16
    |
113 |             offset = await loop.run_in_executor(None, _query_ntp)
114 |             return datetime.now(self.leet_tz) + timedelta(seconds=offset)
115 |         except Exception as exc:
    |                ^^^^^^^^^
116 |             log.warning("NTP query failed, using system time: %s", exc)
117 |             return datetime.now(self.leet_tz)
    |

BLE001 Do not catch blind exception: `Exception`
   --> src/func/watcher.py:133:16
    |
131 |                 accurate.strftime("%Y-%m-%d %H:%M:%S"),
132 |             )
133 |         except Exception as exc:
    |                ^^^^^^^^^
134 |             log.warning("NTP query failed at startup: %s", exc)
135 |             log.info(
    |

UP045 [*] Use `X | None` for type annotations
  --> src/func/webhook.py:17:23
   |
15 |         self.username = username
16 |         self.avatar_url = avatar_url
17 |         self.session: Optional[aiohttp.ClientSession] = None
   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
18 |
19 |     def _build_payload(self, content: str) -> dict:
   |
help: Convert to `X | None`
   |
16 |         self.avatar_url = avatar_url
   -         self.session: Optional[aiohttp.ClientSession] = None
17 +         self.session: aiohttp.ClientSession | None = None
18 |
   |

UP045 [*] Use `X | None` for type annotations
  --> src/func/webhook.py:27:57
   |
25 |         return payload
26 |
27 |     async def send(self, url: str, content: str, thumb: Optional[bytes] = None) -> None:
   |                                                         ^^^^^^^^^^^^^^^
28 |         """Post a message to the webhook, optionally with a thumbnail attachment."""
29 |         try:
   |
help: Convert to `X | None`
   |
26 |
   -     async def send(self, url: str, content: str, thumb: Optional[bytes] = None) -> None:
27 +     async def send(self, url: str, content: str, thumb: bytes | None = None) -> None:
28 |         """Post a message to the webhook, optionally with a thumbnail attachment."""
   |

UP045 [*] Use `X | None` for type annotations
  --> src/func/webhook.py:43:50
   |
41 |             log.error("Failed to send webhook: %s", e)
42 |
43 |     async def fetch_thumbnail(self, url: str) -> Optional[bytes]:
   |                                                  ^^^^^^^^^^^^^^^
44 |         """Download a stream thumbnail and return its raw bytes, or None on failure."""
45 |         url = url.replace("{width}", "500").replace("{height}", "281")
   |
help: Convert to `X | None`
   |
42 |
   -     async def fetch_thumbnail(self, url: str) -> Optional[bytes]:
43 +     async def fetch_thumbnail(self, url: str) -> bytes | None:
44 |         """Download a stream thumbnail and return its raw bytes, or None on failure."""
   |

EXE001 Shebang is present but file is not executable
 --> src/main.py:1:1
  |
1 | #!/usr/bin/python3
  | ^^^^^^^^^^^^^^^^^^
2 | """Entry point: configures logging and starts the StreamWatcher."""
3 | import asyncio
  |

I001 [*] Import block is un-sorted or un-formatted
 --> src/main.py:3:1
  |
1 |   #!/usr/bin/python3
2 |   """Entry point: configures logging and starts the StreamWatcher."""
3 | / import asyncio
4 | | import configparser
5 | | import logging
6 | | import os
7 | | import queue
8 | | from func.watcher import StreamWatcher
  | |______________________________________^
help: Organize imports
  |
7 | import queue
8 +
9 | from func.watcher import StreamWatcher
  |

BLE001 Do not catch blind exception: `Exception`
  --> src/main.py:21:16
   |
19 |         try:
20 |             self.queue.put_nowait(self.format(record))
21 |         except Exception:  # pylint: disable=broad-exception-caught
   |                ^^^^^^^^^
22 |             self.handleError(record)
   |

Found 20 errors.
[*] 13 fixable with the `--fix` option.
Pylint output
************* Module func.watcher
src/func/watcher.py:115:15: W0718: Catching too general exception Exception (broad-exception-caught)
src/func/watcher.py:133:15: W0718: Catching too general exception Exception (broad-exception-caught)

-----------------------------------
Your code has been rated at 9.93/10

Updated: 2026-08-02 23:03 UTC

<!-- ci-results --> ## CI Results | Check | Status | |---|---| | Ruff | ❌ | | Pylint (9.93/10) | ❌ | | Config | ✅ | | Imports | ✅ | <details><summary>Ruff output</summary> ``` I001 [*] Import block is un-sorted or un-formatted --> src/func/twitch.py:2:1 | 1 | """Twitch API client: token management, user ID lookup, stream status.""" 2 | / import asyncio 3 | | import time 4 | | import logging 5 | | from typing import Dict, Optional 6 | | 7 | | import aiohttp 8 | | 9 | | from .models import StreamInfo | |______________________________^ 10 | 11 | log = logging.getLogger(__name__) | help: Organize imports | 2 | import asyncio 3 + import logging 4 | import time - import logging 5 | from typing import Dict, Optional | UP035 `typing.Dict` is deprecated, use `dict` instead --> src/func/twitch.py:5:1 | 3 | import time 4 | import logging 5 | from typing import Dict, Optional | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 6 | 7 | import aiohttp | UP045 [*] Use `X | None` for type annotations --> src/func/twitch.py:24:23 | 22 | self.client_id = client_id 23 | self.client_secret = client_secret 24 | self.session: Optional[aiohttp.ClientSession] = None | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 25 | self._token: Optional[str] = None 26 | self._token_expires: float = 0 | help: Convert to `X | None` | 23 | self.client_secret = client_secret - self.session: Optional[aiohttp.ClientSession] = None 24 + self.session: aiohttp.ClientSession | None = None 25 | self._token: Optional[str] = None | UP045 [*] Use `X | None` for type annotations --> src/func/twitch.py:25:22 | 23 | self.client_secret = client_secret 24 | self.session: Optional[aiohttp.ClientSession] = None 25 | self._token: Optional[str] = None | ^^^^^^^^^^^^^ 26 | self._token_expires: float = 0 | help: Convert to `X | None` | 24 | self.session: Optional[aiohttp.ClientSession] = None - self._token: Optional[str] = None 25 + self._token: str | None = None 26 | self._token_expires: float = 0 | UP006 [*] Use `dict` instead of `Dict` for type annotation --> src/func/twitch.py:80:45 | 78 | raise TwitchAPIError(f"Twitch API error: HTTP {r.status} for {url}") 79 | 80 | async def fetch_user_ids(self, streams: Dict[str, StreamInfo]) -> None: | ^^^^ 81 | """Resolve Twitch login names to user IDs and store them in each StreamInfo.""" 82 | await self.ensure_token() | help: Replace with `dict` | 79 | - async def fetch_user_ids(self, streams: Dict[str, StreamInfo]) -> None: 80 + async def fetch_user_ids(self, streams: dict[str, StreamInfo]) -> None: 81 | """Resolve Twitch login names to user IDs and store them in each StreamInfo.""" | UP006 [*] Use `dict` instead of `Dict` for type annotation --> src/func/twitch.py:90:49 | 88 | log.debug("User ID for %s: %s", user["login"], user["id"]) 89 | 90 | async def fetch_live_streams(self, streams: Dict[str, StreamInfo]) -> Dict[str, dict]: | ^^^^ 91 | """Return a dict of currently live streams keyed by login name.""" 92 | await self.ensure_token() | help: Replace with `dict` | 89 | - async def fetch_live_streams(self, streams: Dict[str, StreamInfo]) -> Dict[str, dict]: 90 + async def fetch_live_streams(self, streams: dict[str, StreamInfo]) -> Dict[str, dict]: 91 | """Return a dict of currently live streams keyed by login name.""" | UP006 [*] Use `dict` instead of `Dict` for type annotation --> src/func/twitch.py:90:75 | 88 | log.debug("User ID for %s: %s", user["login"], user["id"]) 89 | 90 | async def fetch_live_streams(self, streams: Dict[str, StreamInfo]) -> Dict[str, dict]: | ^^^^ 91 | """Return a dict of currently live streams keyed by login name.""" 92 | await self.ensure_token() | help: Replace with `dict` | 89 | - async def fetch_live_streams(self, streams: Dict[str, StreamInfo]) -> Dict[str, dict]: 90 + async def fetch_live_streams(self, streams: Dict[str, StreamInfo]) -> dict[str, dict]: 91 | """Return a dict of currently live streams keyed by login name.""" | I001 [*] Import block is un-sorted or un-formatted --> src/func/watcher.py:2:1 | 1 | """Main orchestrator: polls Twitch and dispatches Discord webhook notifications.""" 2 | / import asyncio 3 | | import logging 4 | | import queue 5 | | import random 6 | | from datetime import datetime, timedelta 7 | | from typing import Dict, Optional 8 | | from zoneinfo import ZoneInfo 9 | | import configparser 10 | | 11 | | import aiohttp 12 | | import ntplib 13 | | 14 | | from .models import StreamInfo 15 | | from .twitch import TwitchClient, TwitchAPIError 16 | | from .webhook import WebhookSender | |__________________________________^ 17 | 18 | log = logging.getLogger(__name__) | help: Organize imports | 2 | import asyncio 3 + import configparser 4 | import logging -------------------------------------------------------------------------------- 9 | from zoneinfo import ZoneInfo - import configparser 10 | -------------------------------------------------------------------------------- 14 | from .models import StreamInfo - from .twitch import TwitchClient, TwitchAPIError 15 + from .twitch import TwitchAPIError, TwitchClient 16 | from .webhook import WebhookSender | UP035 `typing.Dict` is deprecated, use `dict` instead --> src/func/watcher.py:7:1 | 5 | import random 6 | from datetime import datetime, timedelta 7 | from typing import Dict, Optional | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 8 | from zoneinfo import ZoneInfo 9 | import configparser | UP045 [*] Use `X | None` for type annotations --> src/func/watcher.py:28:70 | 26 | """Watches a set of Twitch streams and posts live notifications via Discord webhooks.""" 27 | 28 | def __init__(self, config: configparser.ConfigParser, log_queue: Optional[queue.Queue] = None): | ^^^^^^^^^^^^^^^^^^^^^ 29 | dc = config["DISCORD"] 30 | tw = config["TWITCH"] | help: Convert to `X | None` | 27 | - def __init__(self, config: configparser.ConfigParser, log_queue: Optional[queue.Queue] = None): 28 + def __init__(self, config: configparser.ConfigParser, log_queue: queue.Queue | None = None): 29 | dc = config["DISCORD"] | UP006 [*] Use `dict` instead of `Dict` for type annotation --> src/func/watcher.py:50:23 | 48 | ) 49 | 50 | self.streams: Dict[str, StreamInfo] = { | ^^^^ 51 | name: StreamInfo(name=name) 52 | for raw in tw["streams"].split(",") | help: Replace with `dict` | 49 | - self.streams: Dict[str, StreamInfo] = { 50 + self.streams: dict[str, StreamInfo] = { 51 | name: StreamInfo(name=name) | BLE001 Do not catch blind exception: `Exception` --> src/func/watcher.py:78:28 | 76 | except aiohttp.ClientError as e: 77 | log.error("Network error: %s", e) 78 | except Exception as e: # pylint: disable=broad-exception-caught | ^^^^^^^^^ 79 | log.error("Unexpected tick error: %s", e) 80 | await asyncio.sleep(self.poll_interval) | BLE001 Do not catch blind exception: `Exception` --> src/func/watcher.py:115:16 | 113 | offset = await loop.run_in_executor(None, _query_ntp) 114 | return datetime.now(self.leet_tz) + timedelta(seconds=offset) 115 | except Exception as exc: | ^^^^^^^^^ 116 | log.warning("NTP query failed, using system time: %s", exc) 117 | return datetime.now(self.leet_tz) | BLE001 Do not catch blind exception: `Exception` --> src/func/watcher.py:133:16 | 131 | accurate.strftime("%Y-%m-%d %H:%M:%S"), 132 | ) 133 | except Exception as exc: | ^^^^^^^^^ 134 | log.warning("NTP query failed at startup: %s", exc) 135 | log.info( | UP045 [*] Use `X | None` for type annotations --> src/func/webhook.py:17:23 | 15 | self.username = username 16 | self.avatar_url = avatar_url 17 | self.session: Optional[aiohttp.ClientSession] = None | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 18 | 19 | def _build_payload(self, content: str) -> dict: | help: Convert to `X | None` | 16 | self.avatar_url = avatar_url - self.session: Optional[aiohttp.ClientSession] = None 17 + self.session: aiohttp.ClientSession | None = None 18 | | UP045 [*] Use `X | None` for type annotations --> src/func/webhook.py:27:57 | 25 | return payload 26 | 27 | async def send(self, url: str, content: str, thumb: Optional[bytes] = None) -> None: | ^^^^^^^^^^^^^^^ 28 | """Post a message to the webhook, optionally with a thumbnail attachment.""" 29 | try: | help: Convert to `X | None` | 26 | - async def send(self, url: str, content: str, thumb: Optional[bytes] = None) -> None: 27 + async def send(self, url: str, content: str, thumb: bytes | None = None) -> None: 28 | """Post a message to the webhook, optionally with a thumbnail attachment.""" | UP045 [*] Use `X | None` for type annotations --> src/func/webhook.py:43:50 | 41 | log.error("Failed to send webhook: %s", e) 42 | 43 | async def fetch_thumbnail(self, url: str) -> Optional[bytes]: | ^^^^^^^^^^^^^^^ 44 | """Download a stream thumbnail and return its raw bytes, or None on failure.""" 45 | url = url.replace("{width}", "500").replace("{height}", "281") | help: Convert to `X | None` | 42 | - async def fetch_thumbnail(self, url: str) -> Optional[bytes]: 43 + async def fetch_thumbnail(self, url: str) -> bytes | None: 44 | """Download a stream thumbnail and return its raw bytes, or None on failure.""" | EXE001 Shebang is present but file is not executable --> src/main.py:1:1 | 1 | #!/usr/bin/python3 | ^^^^^^^^^^^^^^^^^^ 2 | """Entry point: configures logging and starts the StreamWatcher.""" 3 | import asyncio | I001 [*] Import block is un-sorted or un-formatted --> src/main.py:3:1 | 1 | #!/usr/bin/python3 2 | """Entry point: configures logging and starts the StreamWatcher.""" 3 | / import asyncio 4 | | import configparser 5 | | import logging 6 | | import os 7 | | import queue 8 | | from func.watcher import StreamWatcher | |______________________________________^ help: Organize imports | 7 | import queue 8 + 9 | from func.watcher import StreamWatcher | BLE001 Do not catch blind exception: `Exception` --> src/main.py:21:16 | 19 | try: 20 | self.queue.put_nowait(self.format(record)) 21 | except Exception: # pylint: disable=broad-exception-caught | ^^^^^^^^^ 22 | self.handleError(record) | Found 20 errors. [*] 13 fixable with the `--fix` option. ``` </details> <details><summary>Pylint output</summary> ``` ************* Module func.watcher src/func/watcher.py:115:15: W0718: Catching too general exception Exception (broad-exception-caught) src/func/watcher.py:133:15: W0718: Catching too general exception Exception (broad-exception-caught) ----------------------------------- Your code has been rated at 9.93/10 ``` </details> _Updated: 2026-08-02 23:03 UTC_
Some checks failed
PR Tests / test (pull_request) Failing after 31s
This pull request can be merged automatically.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin renovate/actions-setup-python-7.x:renovate/actions-setup-python-7.x
git switch renovate/actions-setup-python-7.x

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch master
git merge --no-ff renovate/actions-setup-python-7.x
git switch renovate/actions-setup-python-7.x
git rebase master
git switch master
git merge --ff-only renovate/actions-setup-python-7.x
git switch renovate/actions-setup-python-7.x
git rebase master
git switch master
git merge --no-ff renovate/actions-setup-python-7.x
git switch master
git merge --squash renovate/actions-setup-python-7.x
git switch master
git merge --ff-only renovate/actions-setup-python-7.x
git switch master
git merge renovate/actions-setup-python-7.x
git push origin master
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
wirehack7/DiscordStreamBot!13
No description provided.