jenkins-bot has submitted this change. (
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1166510?usp=email )
Change subject: [bugfix] use self.event_id instead of self.id for mark_as_read
......................................................................
[bugfix] use self.event_id instead of self.id for mark_as_read
- id was renamed to event_id in 203a05c and removed in release 7.0.0
but the mark_as_read method wasn't updated accordingly. Use event_id
now.
- use dataclass for the Notification to enable repr/str method
- update documentation
- update typing hints
- update mypy config
Bug: T398770
Change-Id: If5dca1d2d468068ea4f6a962dfa18afa84cb74e3
---
M .pre-commit-config.yaml
M conftest.py
M pywikibot/echo.py
M pywikibot/site/_extensions.py
4 files changed, 90 insertions(+), 24 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 2292fe2..02695fd 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -122,11 +122,11 @@
# Test for files which already passed in past.
# They should be also used in conftest.py to exclude them from
non-voting mypy test.
files: >
- ^pywikibot/(__metadata__|exceptions|fixes|time)\.py$|
+ ^pywikibot/(__metadata__|echo|exceptions|fixes|time)\.py$|
^pywikibot/(comms|data|families|specialbots)/__init__\.py$|
^pywikibot/families/[a-z][a-z\d]+_family\.py$|
^pywikibot/page/(__init__|_decorators|_revision)\.py$|
^pywikibot/scripts/(?:i18n/)?__init__\.py$|
-
^pywikibot/site/(__init__|_basesite|_decorators|_interwikimap|_upload)\.py$|
+
^pywikibot/site/(__init__|_basesite|_decorators|_extensions|_interwikimap|_upload)\.py$|
^pywikibot/tools/(_logging|_unidata|formatter)\.py$|
^pywikibot/userinterfaces/(__init__|_interface_base|terminal_interface)\.py$
diff --git a/conftest.py b/conftest.py
index 3b00f67..830c04c 100644
--- a/conftest.py
+++ b/conftest.py
@@ -16,12 +16,12 @@
EXCLUDE_PATTERN = re.compile(
r'(?:'
- r'(__metadata__|exceptions|fixes|time)|'
+ r'(__metadata__|echo|exceptions|fixes|time)|'
r'(comms|data|families|specialbots)/__init__|'
r'families/[a-z][a-z\d]+_family|'
r'page/(__init__|_decorators|_revision)|'
r'scripts/(i18n/)?__init__|'
- r'site/(__init__|_basesite|_decorators|_interwikimap|_upload)|'
+ r'site/(__init__|_basesite|_decorators|_extensions|_interwikimap|_upload)|'
r'tools/(_logging|_unidata|formatter)|'
r'userinterfaces/(__init__|_interface_base|terminal_interface)'
r')\.py'
diff --git a/pywikibot/echo.py b/pywikibot/echo.py
index bd135ed..2dcd683 100644
--- a/pywikibot/echo.py
+++ b/pywikibot/echo.py
@@ -1,31 +1,52 @@
"""Classes and functions for working with the Echo extension."""
#
-# (C) Pywikibot team, 2014-2022
+# (C) Pywikibot team, 2014-2025
#
# Distributed under the terms of the MIT license.
#
from __future__ import annotations
+from dataclasses import dataclass
from typing import Any
import pywikibot
+@dataclass(eq=False)
class Notification:
- """A notification issued by the Echo extension."""
+ """A notification issued by the Echo extension.
- def __init__(self, site: pywikibot.site.BaseSite) -> None:
- """Initialize an empty Notification object."""
- self.site = site
+ .. versionchanged:: 3.0.20190204
+ The ``id`` attribute was renamed to ``event_id``, and its type
+ changed from ``str`` to ``int``.
+ .. deprecated:: 3.0.20190204
+ The ``id`` attribute was retained temporarily for backward
+ compatibility, but is deprecated and scheduled for removal.
+
+ .. versionremoved:: 7.0
+ The ``id`` attribute was removed.
+
+ .. versionchanged:: 10.3
+ The class is now defined using the ``@dataclass`` decorator to
+ simplify internal initialization and improve maintainability.
+ """
+
+ site: pywikibot.site.BaseSite
+
+ def __post_init__(self) -> None:
+ """Initialize attributes for an empty Notification object.
+
+ .. versionadded: 10.3
+ """
self.event_id: int | None = None
self.type = None
self.category = None
- self.timestamp = None
- self.page = None
- self.agent = None
- self.read: bool | None = None
+ self.timestamp: pywikibot.Timestamp | None = None
+ self.page: pywikibot.Page | None = None
+ self.agent: pywikibot.User | None = None
+ self.read: pywikibot.Timestamp | bool | None = None
self.content = None
self.revid = None
@@ -33,12 +54,19 @@
def fromJSON(cls, # noqa: N802
site: pywikibot.site.BaseSite,
data: dict[str, Any]) -> Notification:
- """Construct a Notification object from our API's JSON data."""
+ """Construct a Notification object from API JSON data.
+
+ :param site: The pywikibot site object.
+ :param data: The JSON data dictionary representing a
+ notification.
+ :return: An instance of Notification.
+ """
notif = cls(site)
notif.event_id = int(data['id'])
notif.type = data['type']
notif.category = data['category']
+
notif.timestamp = pywikibot.Timestamp.fromtimestampformat(
data['timestamp']['mw'])
@@ -59,8 +87,16 @@
notif.content = data.get('*')
notif.revid = data.get('revid')
+
return notif
def mark_as_read(self) -> bool:
- """Mark the notification as read."""
- return self.site.notifications_mark_read(list=self.id)
+ """Mark the notification as read.
+
+ :return: True if the notification was successfully marked as
+ read, else False.
+ """
+ if self.event_id is None:
+ return False
+
+ return self.site.notifications_mark_read(**{'list': self.event_id})
diff --git a/pywikibot/site/_extensions.py b/pywikibot/site/_extensions.py
index 66ea1ff..e30f130 100644
--- a/pywikibot/site/_extensions.py
+++ b/pywikibot/site/_extensions.py
@@ -6,6 +6,8 @@
#
from __future__ import annotations
+from typing import TYPE_CHECKING, Protocol
+
import pywikibot
from pywikibot.data import api
from pywikibot.echo import Notification
@@ -20,6 +22,34 @@
from pywikibot.tools import merge_unique_dicts
+if TYPE_CHECKING:
+ from pywikibot.site import NamespacesDict
+
+
+class BaseSiteProtocol(Protocol):
+ _proofread_levels: dict[int, str]
+ tokens: dict[str, str]
+
+ def _generator(self, *args, **kwargs) -> api.Request:
+ ...
+
+ def _request(self, **kwargs) -> api.Request:
+ ...
+
+ def _update_page(self, *args, **kwargs) -> None:
+ ...
+
+ def encoding(self) -> str:
+ ...
+
+ @property
+ def namespaces(self, **kwargs) -> NamespacesDict:
+ ...
+
+ def simple_request(self, **kwargs) -> api.Request:
+ ...
+
+
class EchoMixin:
"""APISite mixin for Echo extension."""
@@ -50,15 +80,13 @@
for notification in notifications)
@need_extension('Echo')
- def notifications_mark_read(self, **kwargs) -> bool:
+ def notifications_mark_read(self: BaseSiteProtocol, **kwargs) -> bool:
"""Mark selected notifications as read.
.. seealso:: :api:`echomarkread`
:return: whether the action was successful
"""
- # TODO: ensure that the 'echomarkread' action
- # is supported by the site
kwargs = merge_unique_dicts(kwargs, action='echomarkread',
token=self.tokens['csrf'])
req = self.simple_request(**kwargs)
@@ -74,7 +102,7 @@
"""APISite mixin for ProofreadPage extension."""
@need_extension('ProofreadPage')
- def _cache_proofreadinfo(self, expiry=False) -> None:
+ def _cache_proofreadinfo(self: BaseSiteProtocol, expiry=False) -> None:
"""Retrieve proofreadinfo from site and cache response.
Applicable only to sites with ProofreadPage extension installed.
@@ -142,7 +170,8 @@
return self._proofread_levels
@need_extension('ProofreadPage')
- def loadpageurls(self, page: pywikibot.page.BasePage) -> None:
+ def loadpageurls(self: BaseSiteProtocol,
+ page: pywikibot.page.BasePage) -> None:
"""Load URLs from api and store in page attributes.
Load URLs to images for a given page in the "Page:" namespace.
@@ -169,7 +198,7 @@
"""APISite mixin for GeoData extension."""
@need_extension('GeoData')
- def loadcoordinfo(self, page) -> None:
+ def loadcoordinfo(self: BaseSiteProtocol, page) -> None:
"""Load [[mw:Extension:GeoData]] info."""
title = page.title(with_section=False)
query = self._generator(api.PropertyGenerator,
@@ -187,7 +216,7 @@
"""APISite mixin for PageImages extension."""
@need_extension('PageImages')
- def loadpageimage(self, page) -> None:
+ def loadpageimage(self: BaseSiteProtocol, page) -> None:
"""Load [[mw:Extension:PageImages]] info.
:param page: The page for which to obtain the image
@@ -374,7 +403,8 @@
"""
@need_extension('TextExtracts')
- def extract(self, page: pywikibot.Page, *,
+ def extract(self: BaseSiteProtocol,
+ page: pywikibot.Page, *,
chars: int | None = None,
sentences: int | None = None,
intro: bool = True,
--
To view, visit
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1166510?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.wikimedia.org/r/settings?usp=email
Gerrit-MessageType: merged
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: If5dca1d2d468068ea4f6a962dfa18afa84cb74e3
Gerrit-Change-Number: 1166510
Gerrit-PatchSet: 12
Gerrit-Owner: Xqt <[email protected]>
Gerrit-Reviewer: Xqt <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
Pywikibot-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]