jenkins-bot has submitted this change. (
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1321012?usp=email )
Change subject: solve_disambiguation: Handle replacement sections
......................................................................
solve_disambiguation: Handle replacement sections
Keep the replacement page title and section separate while building the
new link. If a replacement supplies a section, use it instead of appending
the source section.
Bug: T394622
Change-Id: I34595ee176b58f8fa6d20e038272369ead61b3af
---
M scripts/solve_disambiguation.py
A tests/solve_disambiguation_tests.py
2 files changed, 98 insertions(+), 15 deletions(-)
Approvals:
jenkins-bot: Verified
Xqt: Looks good to me, approved
diff --git a/scripts/solve_disambiguation.py b/scripts/solve_disambiguation.py
index d83ff13..c60a061 100755
--- a/scripts/solve_disambiguation.py
+++ b/scripts/solve_disambiguation.py
@@ -976,36 +976,41 @@
else:
replaceit = include == 'redirect'
- new_page_title = answer[1]
- rep = pywikibot.Page(pywikibot.Link(new_page_title,
+ rep = pywikibot.Page(pywikibot.Link(answer[1],
disamb_page.site))
- new_page_title = rep.title()
+ new_page_title = rep.title(with_section=False)
+ new_page_section = rep.section()
if not (new_page_title[0].isupper()
or link_text[0].isupper()):
new_page_title = first_lower(new_page_title)
- if new_page_title not in new_targets:
- new_targets.append(new_page_title)
+ new_link_target = new_page_title + (
+ f'#{new_page_section}' if new_page_section else '')
+ # An explicit replacement section takes precedence.
+ section = section if new_page_section is None else ''
+
+ if new_link_target not in new_targets:
+ new_targets.append(new_link_target)
if replaceit and trailing_chars:
- newlink = f'[[{new_page_title}{section}]]{trailing_chars}'
- elif replaceit or (new_page_title == link_text
+ newlink = f'[[{new_link_target}{section}]]{trailing_chars}'
+ elif replaceit or (new_link_target == link_text
and not section):
- newlink = f'[[{new_page_title}]]'
+ newlink = f'[[{new_link_target}]]'
# check if we can create a link with trailing characters
# instead of a pipelink
elif (
- (len(new_page_title) <= len(link_text))
- and (first_upper(link_text[:len(new_page_title)])
- == first_upper(new_page_title))
+ (len(new_link_target) <= len(link_text))
+ and (first_upper(link_text[:len(new_link_target)])
+ == first_upper(new_link_target))
and (self.trailR.sub(
- '', link_text[len(new_page_title):]) == '')
+ '', link_text[len(new_link_target):]) == '')
and (not section)
):
- newlink = (f'[[{link_text[:len(new_page_title)]}]]'
- f'{link_text[len(new_page_title):]}')
+ newlink = (f'[[{link_text[:len(new_link_target)]}]]'
+ f'{link_text[len(new_link_target):]}')
else:
- newlink = f'[[{new_page_title}{section}|{link_text}]]'
+ newlink = f'[[{new_link_target}{section}|{link_text}]]'
text = text[:match_start] + newlink + text[match_end:]
continue
diff --git a/tests/solve_disambiguation_tests.py
b/tests/solve_disambiguation_tests.py
new file mode 100755
index 0000000..1afb19d
--- /dev/null
+++ b/tests/solve_disambiguation_tests.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python3
+#
+# (C) Pywikibot team, 2026
+#
+# Distributed under the terms of the MIT license.
+#
+"""Tests for the solve_disambiguation script."""
+from __future__ import annotations
+
+import unittest
+from contextlib import suppress
+from unittest.mock import patch
+
+import pywikibot
+from scripts.solve_disambiguation import DisambiguationRobot
+from tests.aspects import TestCase
+
+
+class TestDisambiguationRobot(TestCase):
+
+ """Test the disambiguation bot."""
+
+ family = 'wikipedia'
+ code = 'de'
+ dry = True
+
+ def setUp(self) -> None:
+ """Create a bot for each test."""
+ super().setUp()
+ self.bot = DisambiguationRobot(site=self.site, generator=[])
+ self.bot.setup()
+
+ def _assert_replacement(self, source: str, replacement: str,
+ expected: str) -> None:
+ """Assert the replacement produced by the bot."""
+ self.bot.opt.pos = [replacement]
+ disamb_page = pywikibot.Page(self.site, 'Rasenmähen')
+ ref_page = pywikibot.Page(self.site, 'Beispiel')
+ with patch.object(ref_page, 'get', return_value=source), \
+ patch.object(ref_page, 'put') as put, \
+ patch.object(self.bot, 'setSummaryMessage'), \
+ patch('scripts.solve_disambiguation.ShowPageOption'), \
+ patch('pywikibot.input_choice',
+ return_value=('', replacement)):
+ result = self.bot.treat_disamb_only(ref_page, disamb_page)
+
+ self.assertEqual(result, 'done')
+ put.assert_called_once()
+ self.assertEqual(put.call_args.args[0], expected)
+
+ def test_replacement_section(self) -> None:
+ """Test replacing a link and its section."""
+ self._assert_replacement(
+ '[[Rasenmähen#Rasenmähen|Rasenmähen]]',
+ 'Mähen#Rasenmähen',
+ '[[Mähen#Rasenmähen|Rasenmähen]]',
+ )
+
+ def test_different_replacement_section(self) -> None:
+ """Test that the replacement section overrides the old section."""
+ self._assert_replacement(
+ '[[Rasenmähen#Alt|Rasenmähen]]',
+ 'Mähen#Neu',
+ '[[Mähen#Neu|Rasenmähen]]',
+ )
+
+ def test_source_section(self) -> None:
+ """Test preserving the source section when none replaces it."""
+ self._assert_replacement(
+ '[[Rasenmähen#Alt|Rasenmähen]]',
+ 'Mähen',
+ '[[Mähen#Alt|Rasenmähen]]',
+ )
+
+
+if __name__ == '__main__':
+ with suppress(SystemExit):
+ unittest.main()
--
To view, visit
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1321012?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: I34595ee176b58f8fa6d20e038272369ead61b3af
Gerrit-Change-Number: 1321012
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]