XZise has uploaded a new change for review.
https://gerrit.wikimedia.org/r/231899
Change subject: [FEAT] replaceExcept: Support custom parameters
......................................................................
[FEAT] replaceExcept: Support custom parameters
This adds the ability to support custom parameters when the replacement is a
callable. This can be used to pass the page to the callable in the replace
script.
Bug: T109220
Change-Id: Iee52388d8a137a21252476cb7926e4705e0324fa
---
M pywikibot/textlib.py
M scripts/replace.py
M tests/textlib_tests.py
3 files changed, 65 insertions(+), 11 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/pywikibot/core
refs/changes/99/231899/1
diff --git a/pywikibot/textlib.py b/pywikibot/textlib.py
index 77454fc..bf10b7a 100644
--- a/pywikibot/textlib.py
+++ b/pywikibot/textlib.py
@@ -225,7 +225,8 @@
def replaceExcept(text, old, new, exceptions, caseInsensitive=False,
- allowoverlap=False, marker='', site=None):
+ allowoverlap=False, marker='', site=None,
+ replacement_parameters=None):
"""
Return text with 'old' replaced by 'new', ignoring specified types of text.
@@ -245,8 +246,17 @@
@type caseInsensitive: bool
@param marker: a string that will be added to the last replacement;
if nothing is changed, it is added at the end
-
+ @param replacement_parameters: if C{new} is a callable these parameters
+ are forwarded additionally to the match.
+ @type replacement_parameters: dict or None
"""
+ if replacement_parameters:
+ if not callable(new):
+ raise ValueError('The replacement_parameters cannot be set when '
+ 'the replacement is not callable.')
+ else:
+ replacement_parameters = {}
+
# if we got a string, compile it as a regular expression
if isinstance(old, basestring):
if caseInsensitive:
@@ -289,7 +299,7 @@
if callable(new):
# the parameter new can be a function which takes the match
# as a parameter.
- replacement = new(match)
+ replacement = new(match, **replacement_parameters)
else:
# it is not a function, but a string.
diff --git a/scripts/replace.py b/scripts/replace.py
index 9bcfeb1..981d580 100755
--- a/scripts/replace.py
+++ b/scripts/replace.py
@@ -179,12 +179,14 @@
"""The replacement instructions."""
- def __init__(self, old, new, edit_summary=None, default_summary=True):
+ def __init__(self, old, new, edit_summary=None, default_summary=True,
+ page_parameter=False):
self.old = old
self.old_regex = None
self.new = new
self._edit_summary = edit_summary
self.default_summary = default_summary
+ self.page_parameter = page_parameter
@property
def edit_summary(self):
@@ -287,7 +289,7 @@
"""
def __init__(self, use_regex, exceptions, case_insensitive, edit_summary,
- name):
+ name, page_parameter=False):
super(ReplacementList, self).__init__()
self.use_regex = use_regex
self._exceptions = exceptions
@@ -295,6 +297,7 @@
self.case_insensitive = case_insensitive
self.edit_summary = edit_summary
self.name = name
+ self.page_parameter = page_parameter
def _compile_exceptions(self, use_regex, flags):
if not self.exceptions and self._exceptions is not None:
@@ -343,6 +346,11 @@
Container objects must have a "name" attribute.
"""
return self.fix_set
+
+ @property
+ def page_parameter(self):
+ """Return the page_parameter of the container."""
+ return self.container.page_parameter
def _compile(self, use_regex, flags):
super(ReplacementListEntry, self)._compile(use_regex, flags)
@@ -589,10 +597,15 @@
replacement.description, page.title(asLink=True)))
continue
old_text = new_text
+ if replacement.page_parameter:
+ parameters = {'page': page}
+ else:
+ parameters = {}
new_text = textlib.replaceExcept(
new_text, replacement.old_regex, replacement.new,
exceptions + get_exceptions(replacement.exceptions or {}),
- allowoverlap=self.allowoverlap, site=self.site)
+ allowoverlap=self.allowoverlap, site=self.site,
+ replacement_parameters=parameters)
if old_text != new_text:
applied.add(replacement)
@@ -963,11 +976,9 @@
set_summary = i18n.translate(site, fix['msg'], fallback=True)
else:
set_summary = None
- replacement_set = ReplacementList(fix.get('regex'),
- fix.get('exceptions'),
- fix.get('nocase'),
- set_summary,
- name=fix_name)
+ replacement_set = ReplacementList(
+ fix.get('regex'), fix.get('exceptions'), fix.get('nocase'),
+ set_summary, fix_name, fix.get('pass_page'))
for replacement in fix['replacements']:
summary = None if len(replacement) < 3 else replacement[2]
if chars.contains_invisible(replacement[0]):
diff --git a/tests/textlib_tests.py b/tests/textlib_tests.py
index 1de1fa9..3248878 100644
--- a/tests/textlib_tests.py
+++ b/tests/textlib_tests.py
@@ -1027,6 +1027,39 @@
r'X\g<foo>X', [],
site=self.site),
r'X\g<bar>X')
+ def test_callable_replacement(self):
+ """Test replaceExcept with the replacement being callable."""
+ def no_parameters(match):
+ return 'np'
+
+ def req_parameter(match, value):
+ return value
+
+ def opt_parameter(match, value='nv'):
+ return value
+
+ self.assertEqual(textlib.replaceExcept('barfoo', 'foo', no_parameters,
+ [], site=self.site),
+ 'barnp')
+ self.assertRaises(TypeError, textlib.replaceExcept,
+ 'barfoo', 'foo', no_parameters, [], site=self.site,
+ replacement_parameters={'value': '42'})
+ self.assertRaises(TypeError, textlib.replaceExcept,
+ 'barfoo', 'foo', req_parameter, [], site=self.site)
+ self.assertEqual(
+ textlib.replaceExcept(
+ 'barfoo', 'foo', req_parameter, [], site=self.site,
+ replacement_parameters={'value': '42'}),
+ 'bar42')
+ self.assertEqual(textlib.replaceExcept('barfoo', 'foo', opt_parameter,
+ [], site=self.site),
+ 'barnv')
+ self.assertEqual(
+ textlib.replaceExcept(
+ 'barfoo', 'foo', opt_parameter, [], site=self.site,
+ replacement_parameters={'value': '42'}),
+ 'bar42')
+
if __name__ == '__main__':
try:
--
To view, visit https://gerrit.wikimedia.org/r/231899
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Iee52388d8a137a21252476cb7926e4705e0324fa
Gerrit-PatchSet: 1
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: XZise <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits