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]