jenkins-bot has submitted this change. ( 
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1162017?usp=email )

Change subject: IMPR(GeneratorsMixin.usercontribs): Add all `ucshow` parameters
......................................................................

IMPR(GeneratorsMixin.usercontribs): Add all `ucshow` parameters

MediaWiki core supports are five values (and their negations) for the
`ucshow` parameter, of which one and a half were supported so far:

- `minor` was supported
- `top` was only supported as the deprecated `uctoponly` parameter,
  which generates deprecation warnings, and only works as a positive
  filter (i.e. doesn’t allow filtering for non-top edits)
- `new`, `patrolled` and `autopatrolled` weren’t supported at all

Add support for all five using ternary (`bool|None`) parameters, and
deprecate the old, binary (`bool`) `top_only` parameter at a Pywikibot
level, avoiding the API deprecation warnings.

All five filters has been supported since MediaWiki 1.31 or earlier (the
newest one is `autopatrolled`, which debuted exactly in 1.31: T184791 /
If64ba8b845b122a87f20646dddf72ef257b793cb), so backward compatibility is
not an issue.

This adds support only for core filters. At least the ORES extension
adds an additional filter `oresreview`, but I’m not sure if it’s a good
idea to add an extension-specific filter to a generic query.

Due to kwargs usage the new parameters are also available with
User.contribs and User.contributions.

Add tests for `new` and `top`, but not for `patrolled` and
`autopatrolled`, as the latter two may fail with permission errors,
making the tests flaky.

All parameters are keyword-only now; older usage is deprecated.
Update documentation

Change-Id: I0b67fe74bc2a7412da11374f6968472d40b3759d
---
M pywikibot/page/_user.py
M pywikibot/site/_generators.py
M tests/site_generators_tests.py
3 files changed, 123 insertions(+), 31 deletions(-)

Approvals:
  jenkins-bot: Verified
  Xqt: Looks good to me, approved




diff --git a/pywikibot/page/_user.py b/pywikibot/page/_user.py
index 6f9d486..9a8e8c9 100644
--- a/pywikibot/page/_user.py
+++ b/pywikibot/page/_user.py
@@ -536,6 +536,10 @@
            now accepts ``None`` to iterate both latest and non-latest
            contributions. ``False`` now iterates only non-latest
            contributions. Default is ``None``.
+        .. version-changed:: 11.7
+           The *new*, *patrolled*, *autopatrolled*, *prop* and
+           *formatversion* parameter were added. The ``size`` property
+           is included by default.
         .. seealso::
            - :meth:`contribs`
            - :meth:`Site.usercontribs()
@@ -545,16 +549,31 @@
         :param total: Limit result to this number of pages
         :keyword start: Iterate contributions starting at this Timestamp
         :keyword end: Iterate contributions ending at this Timestamp
-        :keyword reverse: Iterate oldest contributions first (default: newest)
+        :keyword bool reverse: Iterate oldest contributions first
+            (default: newest)
         :keyword namespaces: Only iterate pages in these namespaces
         :type namespaces: Iterable of str or Namespace key,
             or a single instance of those types. May be a '|' separated
             list of namespace identifiers.
-        :keyword minor: If True, iterate only minor edits; if False and
-            not None, iterate only non-minor edits (default: iterate both)
-        :param top: if ``True``, iterate only edits which are the latest
-            revision; if ``False``, do not iterate last revision edits;
-            ``None`` to iterate both (default: ``None``)
+        :keyword bool | None minor: If ``True``, iterate only minor
+            edits; if ``False`` and not ``None``, iterate only non-minor
+            edits (default: iterate both)
+        :keyword bool | None top: if ``True``, iterate only edits which
+            are the latest revision; if ``False``, do not iterate last
+            revision edits; ``None`` to iterate both (default: ``None``)
+        :keyword bool | None new: If ``True``, iterate only edits
+            creating new pages; if ``False``, iterate only edits to
+            existing pages; if ``None``, iterate both.
+        :keyword bool | None patrolled: If ``True``, iterate only edits
+            that have been patrolled (either manually or automatically;
+            use the *autopatrolled* parameter to control how); if
+            ``False``, iterate only edits that haven't been patrolled
+            yet; if ``None``, iterate both; both ``True`` or ``False``
+            exclude edits older than ``$wgRCMaxAge``.
+        :keyword bool | None autopatrolled: If ``True``, iterate only
+            autopatrolled edits; if ``False``, iterate only edits that
+            weren't autopatrolled; if ``None``, iterate both; both
+            ``True`` or ``False`` exclude edits older than ``$wgRCMaxAge``.
         :return: Tuple of pywikibot.Page, revid, pywikibot.Timestamp, comment
         """
         prop = ('comment', 'ids', 'timestamp', 'title')
@@ -598,20 +617,37 @@
              <pywikibot.site._generators.GeneratorsMixin.usercontribs>`
            - :api:`Usercontribs`

+        :keyword int | None total: Limit result to this number of pages
         :keyword start: Iterate contributions starting at this Timestamp
         :keyword end: Iterate contributions ending at this Timestamp
-        :keyword reverse: Iterate oldest contributions first (default:
-            newest)
+        :keyword bool reverse: Iterate oldest contributions first
+            (default: newest)
         :keyword namespaces: Only iterate pages in these namespaces
-        :keyword minor: If ``True``, iterate only minor edits; if ``False``
-            and not ``None``, iterate only non-minor edits (default:
-            iterate both)
-        :keyword total: Limit result to this number of pages
-        :keyword top: if ``True``, iterate only edits which are the latest
-            revision; if ``False``, do not iterate last revision edits;
-            ``None`` to iterate both (default: ``None``)
-        :keyword prop: Include additional pieces of information. Refer
-            :api:`Usercontribs` for the elements and the default setting.
+        :type namespaces: Iterable of str or Namespace key,
+            or a single instance of those types. May be a '|' separated
+            list of namespace identifiers.
+        :keyword bool | None minor: If ``True``, iterate only minor
+            edits; if ``False`` and not ``None``, iterate only non-minor
+            edits (default: iterate both)
+        :keyword bool | None top: if ``True``, iterate only edits which
+            are the latest revision; if ``False``, do not iterate last
+            revision edits; ``None`` to iterate both (default: ``None``)
+        :keyword bool | None new: If ``True``, iterate only edits
+            creating new pages; if ``False``, iterate only edits to
+            existing pages; if ``None``, iterate both.
+        :keyword bool | None patrolled: If ``True``, iterate only edits
+            that have been patrolled (either manually or automatically;
+            use the *autopatrolled* parameter to control how); if
+            ``False``, iterate only edits that haven't been patrolled
+            yet; if ``None``, iterate both; both ``True`` or ``False``
+            exclude edits older than ``$wgRCMaxAge``.
+        :keyword bool | None autopatrolled: If ``True``, iterate only
+            autopatrolled edits; if ``False``, iterate only edits that
+            weren't autopatrolled; if ``None``, iterate both; both
+            ``True`` or ``False`` exclude edits older than ``$wgRCMaxAge``.
+        :keyword Iterable[str] | str | None prop: Include additional
+            pieces of information. Refer :api:`Usercontribs` for the
+            elements and the default setting.
         :return: For each entry return a tuple of Page, Revision
         """
         for contrib in self.site.usercontribs(
diff --git a/pywikibot/site/_generators.py b/pywikibot/site/_generators.py
index 44e2b61..40dd40f 100644
--- a/pywikibot/site/_generators.py
+++ b/pywikibot/site/_generators.py
@@ -1638,8 +1638,10 @@
                                parameters=parameters)

     @deprecated_args(top_only='top')  # since 11.6.0
+    @deprecated_signature(since='10.7.0')
     def usercontribs(
         self,
+        *,
         user: str | None = None,
         userprefix: str | None = None,
         start: pywikibot.time.Timestamp | datetime | str | None = None,
@@ -1649,7 +1651,10 @@
         minor: bool | None = None,
         total: int | None = None,
         top: bool | None = None,
-        *,
+        # old kw args below
+        new: bool | None = None,
+        patrolled: bool | None = None,
+        autopatrolled: bool | None = None,
         prop: Iterable[str] | str | None = None,
         formatversion: int = 1
     ) -> Iterable[dict[str, Any]]:
@@ -1659,32 +1664,51 @@

         .. seealso::
            - :api:`Usercontribs`
+           - :meth:`pywikibot.User.contribs`
            - :meth:`pywikibot.User.contributions`

         .. version-changed:: 3.0.20200609
            The *showMinor* parameter was renamed to *minor*.
+
         .. version-changed:: 11.6
-           The *prop* and *formatversion* parameter were added. The
+           The *prop* and *formatversion* parameters were added. The
            *top_only* was renamed to *top*. This parameter now accepts
            ``None`` to iterate both latest and non-latest contributions.
            ``False`` now iterates only non-latest contributions. Default
            is ``None``. The ``size`` property is included by default.

-        :param user: Iterate contributions by this user (name or IP)
+        .. version-changed:: 11.7
+           All parameters are keyword-only now. The *new*, *patrolled*,
+           and *autopatrolled* parameters were added.
+
+        :param user: Iterate contributions by this user (name or IP).
         :param userprefix: Iterate contributions by all users whose
-            names or IPs start with this substring
-        :param start: Iterate contributions starting at this Timestamp
-        :param end: Iterate contributions ending at this Timestamp
+            names or IPs start with this substring.
+        :param start: Iterate contributions starting at this Timestamp.
+        :param end: Iterate contributions ending at this Timestamp.
         :param reverse: Iterate oldest contributions first (default:
-            newest)
-        :param namespaces: Only iterate pages in these namespaces
+            newest).
+        :param namespaces: Only iterate pages in these namespaces.
         :param minor: If ``True``, iterate only minor edits; if ``False``
             and not ``None``, iterate only non-minor edits (default:
-            iterate both)
-        :param total: Limit result to this number of pages
+            iterate both).
+        :param total: Limit result to this number of pages.
         :param top: if ``True``, iterate only edits which are the latest
             revision; if ``False``, do not iterate last revision edits;
-            ``None`` to iterate both (default: ``None``)
+            ``None`` to iterate both (default: ``None``).
+        :param new: If ``True``, iterate only edits creating new pages;
+            if ``False``, iterate only edits to existing pages; if
+            ``None``, iterate both.
+        :param patrolled: If ``True``, iterate only edits that have been
+            patrolled (either manually or automatically; use the
+            *autopatrolled* parameter to control how); if ``False``,
+            iterate only edits that haven't been patrolled yet; if
+            ``None``, iterate both; both ``True`` or ``False`` exclude
+            edits older than ``$wgRCMaxAge``.
+        :param autopatrolled: If ``True``, iterate only autopatrolled
+            edits; if ``False``, iterate only edits that weren't
+            autopatrolled; if ``None``, iterate both; both ``True`` or
+            ``False`` exclude edits older than ``$wgRCMaxAge``.
         :param prop: Include additional pieces of information. Refer
             :api:`Usercontribs` for the elements and the default setting.
         :param formatversion: The API format version to use for the
@@ -1718,9 +1742,15 @@
             ucgen.request['ucuserprefix'] = userprefix
         if reverse:
             ucgen.request['ucdir'] = 'newer'
-        option_set = api.OptionSet(self, 'usercontribs', 'show')
-        option_set['minor'] = minor
-        option_set['top'] = top
+
+        filters = {
+            'minor': minor,
+            'top': top,
+            'new': new,
+            'patrolled': patrolled,
+            'autopatrolled': autopatrolled,
+        }
+        option_set = api.OptionSet(self, 'usercontribs', 'show', filters)
         ucgen.request['ucshow'] = option_set
         return ucgen

diff --git a/tests/site_generators_tests.py b/tests/site_generators_tests.py
index d01d0fa..eb5d493 100755
--- a/tests/site_generators_tests.py
+++ b/tests/site_generators_tests.py
@@ -1177,6 +1177,32 @@
             self.assertIsInstance(contrib, dict)
             self.assertNotIn('minor', contrib)

+    def test_show_new(self) -> None:
+        """Test the site.usercontribs() method using showMinor."""
+        mysite = self.get_site()
+        for contrib in mysite.usercontribs(user=mysite.user(),
+                                           new=True, total=5):
+            self.assertIsInstance(contrib, dict)
+            self.assertIn('new', contrib)
+
+        for contrib in mysite.usercontribs(user=mysite.user(),
+                                           new=False, total=5):
+            self.assertIsInstance(contrib, dict)
+            self.assertNotIn('new', contrib)
+
+    def test_show_top(self) -> None:
+        """Test the site.usercontribs() method using showMinor."""
+        mysite = self.get_site()
+        for contrib in mysite.usercontribs(user=mysite.user(),
+                                           top=True, total=5):
+            self.assertIsInstance(contrib, dict)
+            self.assertIn('top', contrib)
+
+        for contrib in mysite.usercontribs(user=mysite.user(),
+                                           top=False, total=5):
+            self.assertIsInstance(contrib, dict)
+            self.assertNotIn('top', contrib)
+

 class TestUserContribsWithoutUser(DefaultSiteTestCase):


--
To view, visit 
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1162017?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: I0b67fe74bc2a7412da11374f6968472d40b3759d
Gerrit-Change-Number: 1162017
Gerrit-PatchSet: 9
Gerrit-Owner: Tacsipacsi <[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]

Reply via email to