Xqt has submitted this change. ( 
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/843988 )

Change subject: [IMPR] Allow all Site.categorymembers() parameters for 
Category.subcategories()
......................................................................

[IMPR] Allow all Site.categorymembers() parameters for Category.subcategories()

- enable all parameters of Site.categorymembers()  with
  Category.subcategories() method
- drop cache because a lot of parameters are used now
- call Category.members() to implement Category.subcategories to prevent
  code duplication
- update tests

Change-Id: Iad5570767cbe497e107d8b8f989bc50a7ef16560
---
M pywikibot/page/_category.py
M tests/category_tests.py
2 files changed, 30 insertions(+), 111 deletions(-)

Approvals:
  Xqt: Verified; Looks good to me, approved



diff --git a/pywikibot/page/_category.py b/pywikibot/page/_category.py
index 173bf67..d6ea85f 100644
--- a/pywikibot/page/_category.py
+++ b/pywikibot/page/_category.py
@@ -58,25 +58,38 @@
             title_with_sort_key += '|' + key
         return f'[[{title_with_sort_key}]]'

-    def subcategories(self,
+    def subcategories(self, *,
                       recurse: Union[int, bool] = False,
-                      total: Optional[int] = None,
-                      content: bool = False):
-        """
-        Iterate all subcategories of the current category.
+                      **kwargs: Any) -> Iterable[Page]:
+        """Iterate all subcategories of the current category.

-        :param recurse: if not False or 0, also iterate subcategories of
+        **Usage:**
+
+        >>> site = pywikibot.Site('wikipedia:en')
+        >>> cat = pywikibot.Category(site, 'Contents')
+        >>> next(cat.subcategories())
+        Category('Category:Wikipedia administration')
+        >>> len(list(cat.subcategories(recurse=2, total=50)))
+        50
+
+        .. seealso:: :attr:`categoryinfo`
+
+        .. versionchanged:: 8.0
+           all parameters are keyword arguments only. Additional
+           parameters are supported.
+
+        :param recurse: if not False or 0, also iterate articles in
             subcategories. If an int, limit recursion to this number of
-            levels. (Example: recurse=1 will iterate direct subcats and
-            first-level sub-sub-cats, but no deeper.)
-        :param total: iterate no more than this number of
-            subcategories in total (at all levels)
-        :param content: if True, retrieve the content of the current version
-            of each category description page (default False)
+            levels. (Example: ``recurse=1`` will iterate articles in
+            first-level subcats, but no deeper.)
+        :param kwargs: Additional parameters. Refer to
+            :meth:`APISite.categorymembers()
+            <pywikibot.site._generators.GeneratorsMixin.categorymembers>`
+            for complete list (*member_type* excluded).
         """
-
-        def is_cache_valid(cache: dict, content: bool) -> bool:
-            return cache['content'] or not content
+        if kwargs.pop('member_type', False):
+            raise TypeError('subcategories() got an unexpected keyword '
+                            "argument 'member_type'")

         if not self.categoryinfo['subcats']:
             return
@@ -84,50 +97,8 @@
         if not isinstance(recurse, bool) and recurse:
             recurse -= 1

-        if (not hasattr(self, '_subcats')
-                or not is_cache_valid(self._subcats, content)):
-            cache = {'data': [], 'content': content}
-
-            for subcat in self.site.categorymembers(
-                    self, member_type='subcat', total=total, content=content):
-                cache['data'].append(subcat)
-                yield subcat
-                if total is not None:
-                    total -= 1
-                    if total == 0:
-                        return
-
-                if recurse:
-                    for item in subcat.subcategories(
-                            recurse, total=total, content=content):
-                        yield item
-                        if total is None:
-                            continue
-
-                        total -= 1
-                        if total == 0:
-                            return
-
-            # cache is valid only if all subcategories are fetched (T88217)
-            self._subcats = cache
-        else:
-            for subcat in self._subcats['data']:
-                yield subcat
-                if total is not None:
-                    total -= 1
-                    if total == 0:
-                        return
-
-                if recurse:
-                    for item in subcat.subcategories(
-                            recurse, total=total, content=content):
-                        yield item
-                        if total is None:
-                            continue
-
-                        total -= 1
-                        if total == 0:
-                            return
+        yield from self.members(member_type='subcat', recurse=recurse,
+                                **kwargs)

     def articles(self, *,
                  recurse: Union[int, bool] = False,
diff --git a/tests/category_tests.py b/tests/category_tests.py
index 3bd8f1f..862ed62 100755
--- a/tests/category_tests.py
+++ b/tests/category_tests.py
@@ -107,58 +107,6 @@
         subcategories_total = list(cat.subcategories(total=2))
         self.assertLength(subcategories_total, 2)

-    def test_subcategories_cache_length(self):
-        """Test the subcategories cache length."""
-        site = self.get_site()
-
-        # test cache is valid only if all members of cat are iterated.
-        cat = pywikibot.Category(site, 'Category:Wikipedians by gender')
-        subcategories = list(cat.subcategories(total=2))
-        self.assertLength(subcategories, 2)
-        self.assertFalse(hasattr(cat, '_subcats'))
-
-        subcategories = list(cat.subcategories())
-        self.assertGreater(len(subcategories), 2)
-        self.assertTrue(hasattr(cat, '_subcats'))
-
-        # new cat, no cached data.
-        cat = pywikibot.Category(site, 'Category:Wikipedians by gender')
-
-        # cache not available yet due to partial iteration.
-        gen = cat.subcategories()
-        _ = next(gen)
-        self.assertFalse(hasattr(cat, '_subcats'))
-
-        # cache available.
-        _ = list(gen)
-        self.assertTrue(hasattr(cat, '_subcats'))
-
-    def test_subcategories_cache_content(self):
-        """Test the subcategories cache content."""
-        site = self.get_site()
-        cat = pywikibot.Category(site, 'Category:Wikipedians by gender')
-
-        subcategories = list(cat.subcategories(content=False))
-        cache_id_1 = id(cat._subcats)
-        cache_len_1 = len(subcategories)
-        subcat = subcategories[0]
-        self.assertFalse(subcat.has_content())
-
-        # toggle content.
-        subcategories = list(cat.subcategories(content=True))
-        cache_len_2 = len(subcategories)
-        cache_id_2 = id(cat._subcats)
-        subcat = subcategories[0]
-        self.assertTrue(subcat.has_content())
-        # cache reloaded.
-        self.assertNotEqual(cache_id_1, cache_id_2)
-        self.assertTrue(cache_len_1, cache_len_2)
-
-        # cache not reloaded.
-        _ = list(cat.subcategories(content=True))
-        cache_id_3 = id(cat._subcats)
-        self.assertEqual(cache_id_2, cache_id_3)
-
     def test_subcategories_recurse(self):
         """Test the subcategories method with recurse=True."""
         site = self.get_site()

--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/843988
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.wikimedia.org/r/settings

Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: Iad5570767cbe497e107d8b8f989bc50a7ef16560
Gerrit-Change-Number: 843988
Gerrit-PatchSet: 3
Gerrit-Owner: Xqt <[email protected]>
Gerrit-Reviewer: Mpaa <[email protected]>
Gerrit-Reviewer: Xqt <[email protected]>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged
_______________________________________________
Pywikibot-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to