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

Change subject: Add new property APISite.restrictions
......................................................................

Add new property APISite.restrictions

The new property also gives 'cascadinglevels' and 'semiprotectedlevels'.
It shortens APISite.siteinfo['restrictions'] to APISite.restrictions
but the values are sets instead of lists.

APISite methods protection_types() and protection_levels() have been
deprecated and replaced.

This also solves Bug: T404309

Change-Id: I7199e78c6600beb21736031e8f4a4a13a3cc27f4
---
M pywikibot/site/_apisite.py
M pywikibot/site/_generators.py
M scripts/protect.py
M tests/site_generators_tests.py
M tests/siteinfo_tests.py
5 files changed, 71 insertions(+), 47 deletions(-)

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




diff --git a/pywikibot/site/_apisite.py b/pywikibot/site/_apisite.py
index c4f2764..627d4d2 100644
--- a/pywikibot/site/_apisite.py
+++ b/pywikibot/site/_apisite.py
@@ -1566,7 +1566,7 @@

         :raises ValueError: invalid action parameter
         """
-        if action not in self.siteinfo.get('restrictions')['types']:
+        if action not in self.restrictions['types']:
             raise ValueError(
                 f'{type(self).__name__}.page_can_be_edited(): '
                 f'Invalid value "{action}" for "action" parameter'
@@ -2788,6 +2788,61 @@
         finally:
             self.unlock_page(page)

+    @deprecated("the 'restrictions' property", since='10.5.0')
+    def protection_types(self) -> set[str]:
+        """Return the protection types available on this site.
+
+        **Example:**
+
+        >>> site = pywikibot.Site('wikipedia:test')
+        >>> sorted(site.protection_types())
+        ['create', 'edit', 'move', 'upload']
+
+        .. deprecated:: 10.5
+           Use :attr:`restrictions[types]<restrictions>` instead.
+
+        :return: protection types available
+        """
+        return self.restrictions['types']
+
+    @deprecated("the 'restrictions' property", since='10.5.0')
+    def protection_levels(self) -> set[str]:
+        """Return the protection levels available on this site.
+
+        **Example:**
+
+        >>> site = pywikibot.Site('wikipedia:test')
+        >>> sorted(site.protection_levels())
+        ['', 'autoconfirmed', ... 'sysop', 'templateeditor']
+
+        .. deprecated:: 10.5
+           Use :attr:`restrictions[levels]<restrictions>` instead.
+
+        :return: protection levels available
+        """
+        return self.restrictions['levels']
+
+    @property
+    def restrictions(self) -> dict[str, set[str]]:
+        """Return the page restrictions available on this site.
+
+        **Example:**
+
+        >>> site = pywikibot.Site('wikipedia:test')
+        >>> r = site.restrictions
+        >>> sorted(r['types'])
+        ['create', 'edit', 'move', 'upload']
+        >>> sorted(r['levels'])
+        ['', 'autoconfirmed', ... 'sysop', 'templateeditor']
+
+        .. versionadded:: 10.5
+        .. seealso:: :meth:`page_restrictions`
+
+        :return: dict with keys 'types', 'levels', 'cascadinglevels' and
+            'semiprotectedlevels', all as sets of strings
+        """
+        return {k: set(v) for k, v in self.siteinfo['restrictions'].items()}
+
     _protect_errors = {
         'noapiwrite': 'API editing not enabled on {site} wiki',
         'writeapidenied': 'User {user} not allowed to edit through the API',
@@ -2799,36 +2854,6 @@
         'protect-invalidlevel': 'Invalid protection level'
     }

-    def protection_types(self) -> set[str]:
-        """Return the protection types available on this site.
-
-        **Example:**
-
-        >>> site = pywikibot.Site('wikipedia:test')
-        >>> sorted(site.protection_types())
-        ['create', 'edit', 'move', 'upload']
-
-        .. seealso:: :py:obj:`Siteinfo._get_default()`
-
-        :return: protection types available
-        """
-        return set(self.siteinfo.get('restrictions')['types'])
-
-    def protection_levels(self) -> set[str]:
-        """Return the protection levels available on this site.
-
-        **Example:**
-
-        >>> site = pywikibot.Site('wikipedia:test')
-        >>> sorted(site.protection_levels())
-        ['', 'autoconfirmed', ... 'sysop', 'templateeditor']
-
-        .. seealso:: :py:obj:`Siteinfo._get_default()`
-
-        :return: protection types available
-        """
-        return set(self.siteinfo.get('restrictions')['levels'])
-
     @need_right('protect')
     def protect(
         self,
@@ -2842,15 +2867,14 @@

         .. seealso::
            - :meth:`page.BasePage.protect`
-           - :meth:`protection_types`
-           - :meth:`protection_levels`
+           - :attr:`restrictions`
+           - :meth:`page_restrictions`
            - :api:`Protect`

         :param protections: A dict mapping type of protection to
-            protection level of that type. Refer :meth:`protection_types`
-            for valid restriction types and :meth:`protection_levels`
-            for valid restriction levels. If None is given, however,
-            that protection will be skipped.
+            protection level of that type. Refer :meth:`restrictions`
+            for valid restriction types restriction levels. If None is
+            given, however, that protection will be skipped.
         :param reason: Reason for the action
         :param expiry: When the block should expire. This expiry will be
             applied to all protections. If ``None``, ``'infinite'``,
diff --git a/pywikibot/site/_generators.py b/pywikibot/site/_generators.py
index 9ba50f0..9901495 100644
--- a/pywikibot/site/_generators.py
+++ b/pywikibot/site/_generators.py
@@ -2346,7 +2346,7 @@
         """
         return self.querypage('Listredirects', total)

-    @deprecate_arg('type', 'protect_type')
+    @deprecate_arg('type', 'protect_type')  # since 9.0
     def protectedpages(
         self,
         namespace: NamespaceArgType = 0,
@@ -2368,13 +2368,13 @@
         :param namespace: The searched namespace.
         :param protect_type: The protection type to search for
             (default 'edit').
-        :param level: The protection level (like 'autoconfirmed'). If False it
-            shows all protection levels.
+        :param level: The protection level (like 'autoconfirmed'). If
+            False it shows all protection levels.
         :return: The pages which are protected.
         """
         namespaces = self.namespaces.resolve(namespace)
         # always assert, so we are be sure that protect_type could be 'create'
-        assert 'create' in self.protection_types(), \
+        assert 'create' in self.restrictions['types'], \
             "'create' should be a valid protection type."
         if protect_type == 'create':
             return self._generator(
diff --git a/scripts/protect.py b/scripts/protect.py
index 4efbbd4..b462e7a 100755
--- a/scripts/protect.py
+++ b/scripts/protect.py
@@ -56,7 +56,7 @@
 #
 # Created by modifying delete.py
 #
-# (C) Pywikibot team, 2008-2023
+# (C) Pywikibot team, 2008-2025
 #
 # Distributed under the terms of the MIT license.
 #
@@ -172,11 +172,11 @@
     site = pywikibot.Site()

     generator_type = None
-    protection_levels = site.protection_levels()
+    protection_levels = site.restrictions['levels']
     if '' in protection_levels:
         protection_levels.add('all')

-    protection_types = site.protection_types()
+    protection_types = site.restrictions['types']
     gen_factory = pagegenerators.GeneratorFactory()
     for arg in local_args:
         option, sep, value = arg.partition(':')
diff --git a/tests/site_generators_tests.py b/tests/site_generators_tests.py
index 92e4443..8b38a9e 100755
--- a/tests/site_generators_tests.py
+++ b/tests/site_generators_tests.py
@@ -608,7 +608,7 @@
         """Test protectedpages protection level."""
         site = self.get_site()
         levels = set()
-        all_levels = site.protection_levels().difference([''])
+        all_levels = site.restrictions['levels'].difference([''])
         for level in all_levels:
             if list(site.protectedpages(protect_type='edit', level=level,
                                         total=1)):
diff --git a/tests/siteinfo_tests.py b/tests/siteinfo_tests.py
index 577b5a6..4cb7165 100755
--- a/tests/siteinfo_tests.py
+++ b/tests/siteinfo_tests.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python3
 """Tests for the site module."""
 #
-# (C) Pywikibot team, 2008-2022
+# (C) Pywikibot team, 2008-2025
 #
 # Distributed under the terms of the MIT license.
 #
@@ -64,7 +64,7 @@
         self.assertIn({'ext': 'png'}, fileextensions)
         # restrictions
         self.assertIn('restrictions', self.site.siteinfo)
-        restrictions = self.site.siteinfo.get('restrictions')
+        restrictions = self.site.restrictions
         self.assertIsInstance(restrictions, dict)
         self.assertIn('cascadinglevels', restrictions)


--
To view, visit 
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/154390?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: I7199e78c6600beb21736031e8f4a4a13a3cc27f4
Gerrit-Change-Number: 154390
Gerrit-PatchSet: 16
Gerrit-Owner: Ricordisamoa <[email protected]>
Gerrit-Reviewer: John Vandenberg <[email protected]>
Gerrit-Reviewer: Merlijn van Deen <[email protected]>
Gerrit-Reviewer: Mpaa <[email protected]>
Gerrit-Reviewer: Ricordisamoa <[email protected]>
Gerrit-Reviewer: XZise <[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