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]

Reply via email to