Xqt has submitted this change. ( 
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1324226?usp=email )

Change subject: commonscat: Reuse normalized page titles
......................................................................

commonscat: Reuse normalized page titles

Normalize the full page title once when inferring link text.
Reuse the namespace-free title across replacement decisions.

Keep the substitution in one place to avoid duplicating page loading and
replacement logic across mutually exclusive branches.

Change-Id: I93cb85eff2e870103a36a14f5087802ba22ca9dc
---
M scripts/commonscat.py
M tests/__init__.py
A tests/commonscat_tests.py
3 files changed, 99 insertions(+), 17 deletions(-)

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




diff --git a/scripts/commonscat.py b/scripts/commonscat.py
index 9ce1428..39f529f 100755
--- a/scripts/commonscat.py
+++ b/scripts/commonscat.py
@@ -350,28 +350,26 @@
         if '3=S' in (oldcat, linktitle):
             return  # TODO: handle additional param on de-wiki

-        if not linktitle and (page.title().lower() in oldcat.lower()
-                              or oldcat.lower() in page.title().lower()):
-            linktitle = oldcat
+        if not linktitle:
+            page_title_lower = page.title().lower()
+            oldcat_lower = oldcat.lower()
+            if (page_title_lower in oldcat_lower
+                    or oldcat_lower in page_title_lower):
+                linktitle = oldcat

-        if linktitle and newcat != page.title(with_ns=False):
-            newtext = re.sub(r'(?i)\{\{%s\|?[^{}]*(?:\{\{.*\}\})?\}\}'
-                             % oldtemplate,
-                             f'{{{{{newtemplate}|{newcat}|{linktitle}}}}}',
-                             page.get())
-        elif newcat == page.title(with_ns=False):
-            newtext = re.sub(r'(?i)\{\{%s\|?[^{}]*(?:\{\{.*\}\})?\}\}'
-                             % oldtemplate,
-                             '{{%s}}' % newtemplate,
-                             page.get())
+        page_title = page.title(with_ns=False)
+        if linktitle and newcat != page_title:
+            replacement = f'{{{{{newtemplate}|{newcat}|{linktitle}}}}}'
+        elif newcat == page_title:
+            replacement = '{{%s}}' % newtemplate
         elif oldcat.strip() != newcat:  # strip trailing white space
-            newtext = re.sub(r'(?i)\{\{%s\|?[^{}]*(?:\{\{.*\}\})?\}\}'
-                             % oldtemplate,
-                             f'{{{{{newtemplate}|{newcat}}}}}',
-                             page.get())
+            replacement = f'{{{{{newtemplate}|{newcat}}}}}'
         else:  # nothing left to do
             return

+        newtext = re.sub(r'(?i)\{\{%s\|?[^{}]*(?:\{\{.*\}\})?\}\}'
+                         % oldtemplate, replacement, page.get())
+
         comment = self.opt.summary or i18n.twtranslate(
             page.site, 'commonscat-msg_change', {'oldcat': oldcat,
                                                  'newcat': newcat})
diff --git a/tests/__init__.py b/tests/__init__.py
index d1a6ab2..a0e0611 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -179,6 +179,7 @@
     'cache',
     'category_bot',
     'checkimages',
+    'commonscat',
     'data_ingestion',
     'deletionbot',
     'fixing_redirects',
diff --git a/tests/commonscat_tests.py b/tests/commonscat_tests.py
new file mode 100755
index 0000000..f0f8055
--- /dev/null
+++ b/tests/commonscat_tests.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python3
+#
+# (C) Pywikibot team, 2026
+#
+# Distributed under the terms of the MIT license.
+#
+"""Unit tests for commonscat script."""
+from __future__ import annotations
+
+import unittest
+from unittest.mock import MagicMock, call
+
+from scripts.commonscat import CommonscatBot
+from tests.aspects import TestCase
+
+
+class TestCommonscatBot(TestCase):
+
+    """Test CommonscatBot methods."""
+
+    dry = True
+
+    def test_change_commonscat_reuses_page_data(self) -> None:
+        """Test that changing a Commons category reuses page data."""
+        page = MagicMock()
+        page.title.side_effect = lambda with_ns=True: (
+            'Category:New category' if with_ns else 'New category')
+        page.text = '{{Old|New category}}'
+        page.get.return_value = page.text
+        bot = MagicMock()
+        bot.opt.summary = 'summary'
+
+        CommonscatBot.changeCommonscat(
+            bot, page, 'Old', 'New category', 'New', 'New category')
+
+        self.assertEqual(page.title.call_args_list,
+                         [call(), call(with_ns=False)])
+        page.get.assert_called_once_with()
+        bot.userPut.assert_called_once_with(
+            page, page.text, '{{New}}', summary='summary',
+            ignore_save_related_errors=True)
+
+    def test_change_commonscat_replacement_branches(self) -> None:
+        """Test the remaining Commons category replacement branches."""
+        cases = (
+            ('Link title', '{{New|New category|Link title}}'),
+            ('', '{{New|New category}}'),
+        )
+        for linktitle, expected in cases:
+            with self.subTest(linktitle=linktitle):
+                page = MagicMock()
+                page.title.side_effect = lambda with_ns=True: (
+                    'Category:Page' if with_ns else 'Page')
+                page.text = '{{Old|Old category}}'
+                page.get.return_value = page.text
+                bot = MagicMock()
+                bot.opt.summary = 'summary'
+
+                CommonscatBot.changeCommonscat(
+                    bot, page, 'Old', 'Old category', 'New',
+                    'New category', linktitle)
+
+                page.get.assert_called_once_with()
+                bot.userPut.assert_called_once_with(
+                    page, page.text, expected, summary='summary',
+                    ignore_save_related_errors=True)
+
+    def test_change_commonscat_unchanged(self) -> None:
+        """Test that unchanged Commons categories do not load page text."""
+        page = MagicMock()
+        page.title.side_effect = lambda with_ns=True: (
+            'Category:Page' if with_ns else 'Page')
+        bot = MagicMock()
+
+        CommonscatBot.changeCommonscat(
+            bot, page, 'Old', 'Same category', 'New', 'Same category')
+
+        page.get.assert_not_called()
+        bot.userPut.assert_not_called()
+
+
+if __name__ == '__main__':
+    unittest.main()

--
To view, visit 
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1324226?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: I93cb85eff2e870103a36a14f5087802ba22ca9dc
Gerrit-Change-Number: 1324226
Gerrit-PatchSet: 4
Gerrit-Owner: Mahveotm <[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