jenkins-bot has submitted this change. (
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1351448?usp=email )
Change subject: Build strings from joined fragments
......................................................................
Build strings from joined fragments
Collect replacement, date-pattern and displayed-list fragments before
joining them. Avoid repeatedly copying the accumulated string on Python
implementations without concatenation optimizations.
Preserve output order, whitespace and replacement-group handling.
Change-Id: Ia2cfa782412c78382d322b7c5baa7b01c51a3d6a
---
M pywikibot/bot_choice.py
M pywikibot/date.py
M pywikibot/pagegenerators/_factory.py
M pywikibot/textlib.py
4 files changed, 38 insertions(+), 39 deletions(-)
Approvals:
jenkins-bot: Verified
Xqt: Looks good to me, approved
diff --git a/pywikibot/bot_choice.py b/pywikibot/bot_choice.py
index 4951f27..46ca97b 100644
--- a/pywikibot/bot_choice.py
+++ b/pywikibot/bot_choice.py
@@ -533,15 +533,15 @@
@property
def out(self) -> str:
"""Output text of the enumerated list."""
- text = ''
+ text_parts = []
if self.pre is not None:
- text = self.pre + '\n'
+ text_parts.append(self.pre + '\n')
width = len(str(self.maximum))
- for i, item in enumerate(self._list, self.minimum):
- text += f'{i:>{width}} - {item}\n'
+ text_parts.extend(f'{i:>{width}} - {item}\n'
+ for i, item in enumerate(self._list, self.minimum))
if self.post is not None:
- text += self.post + '\n'
- return text
+ text_parts.append(self.post + '\n')
+ return ''.join(text_parts)
class MultipleChoiceList(ListOption):
diff --git a/pywikibot/date.py b/pywikibot/date.py
index 56bcab0..b9f0ecb 100644
--- a/pywikibot/date.py
+++ b/pywikibot/date.py
@@ -404,37 +404,35 @@
compiled regex object and a list of digit decoders.
"""
@singledispatch
- def decode(dec: decoder_type, subpattern: str, newpattern: str,
- strpattern: str) -> tuple[str, str]:
+ def decode(dec: decoder_type, subpattern: str) -> tuple[str, str]:
if len(subpattern) == 3:
# enforce mandatory field size
- newpattern += f'([{dec[0]}]{{{subpattern[1]}}})'
+ newpattern = f'([{dec[0]}]{{{subpattern[1]}}})'
# add the number of required digits as the last (4th)
# part of the tuple
decoders.append((*dec, int(s[1])))
else:
- newpattern += f'([{dec[0]}]+)'
+ newpattern = f'([{dec[0]}]+)'
decoders.append(dec)
- # All encoders produce a string for strpattern.
+ # All encoders produce a string for the format placeholder.
# This causes problem with the zero padding.
# Need to rethink
- return newpattern, strpattern + '%s'
+ return newpattern, '%s'
@decode.register(str)
- def _(dec: str, subpattern: str, newpattern: str,
- strpattern: str) -> tuple[str, str]:
+ def _(dec: str, subpattern: str) -> tuple[str, str]:
# Special case for strings that are replaced instead of decoded
- # Keep the original text for strPattern
+ # Keep the original text for the format placeholder
assert len(subpattern) < 3, (
f'Invalid pattern {pattern}: Cannot use zero padding size '
f'in {subpattern}!')
- return newpattern + re.escape(dec), strpattern + subpattern
+ return re.escape(dec), subpattern
- newPattern = '' # match starts at the beginning of the string
- strPattern = ''
+ regex_parts = [] # match starts at the beginning of the string
+ string_parts = []
decoders: list[decoder_type] = []
for s in _reParameters.split(pattern):
if s is None:
@@ -444,14 +442,15 @@
and (len(s) == 2 or s[1] in _decimalDigits)):
# Must match a "%2d" or "%d" style
dec = _digitDecoders[s[-1]]
- newPattern, strPattern = decode(dec, s, newPattern, strPattern)
+ regex_part, string_part = decode(dec, s)
else:
- newPattern += re.escape(s)
- strPattern += s
+ regex_part, string_part = re.escape(s), s
+ regex_parts.append(regex_part)
+ string_parts.append(string_part)
- newPattern += '$' # end of the string
- compiledPattern = re.compile(newPattern)
- return compiledPattern, strPattern, decoders
+ regex_parts.append('$') # end of the string
+ compiledPattern = re.compile(''.join(regex_parts))
+ return compiledPattern, ''.join(string_parts), decoders
@singledispatch
diff --git a/pywikibot/pagegenerators/_factory.py
b/pywikibot/pagegenerators/_factory.py
index 740c6b1..31439be 100644
--- a/pywikibot/pagegenerators/_factory.py
+++ b/pywikibot/pagegenerators/_factory.py
@@ -502,12 +502,11 @@
) -> None:
_i = ' ' * 4
_2i = 2 * _i
- txt = 'Available categories of lint errors:\n'
+ text_parts = ['Available categories of lint errors:\n']
for prio, _list in cats.items():
- txt += f'{_i}{prio}\n'
- txt += ''.join(
- f'{_2i}{c}\n' for c in _list)
- pywikibot.info(txt)
+ text_parts.append(f'{_i}{prio}\n')
+ text_parts.extend(f'{_2i}{c}\n' for c in _list)
+ pywikibot.info(''.join(text_parts))
if cat == 'show': # Display categories of lint errors.
show_available_categories(cats)
@@ -536,12 +535,12 @@
'limit')
max_w = max(len(p) for p in pages[::2]) + 4
- txt = 'Available special pages:\n'
- for a, b in zip_longest(pages[::2], pages[1::2], fillvalue=''):
- txt += f' {a:<{max_w}}{b}\n'
- txt += ('\nMaximum number of pages to return is {max} '
- '({highmax} for bots).\n'.format_map(limit))
- pywikibot.info(txt)
+ text_parts = ['Available special pages:\n']
+ text_parts.extend(f' {a:<{max_w}}{b}\n' for a, b in zip_longest(
+ pages[::2], pages[1::2], fillvalue=''))
+ text_parts.append('\nMaximum number of pages to return is {max} '
+ '({highmax} for bots).\n'.format_map(limit))
+ pywikibot.info(''.join(text_parts))
sys.exit(0)
return self.site.querypage(value)
diff --git a/pywikibot/textlib.py b/pywikibot/textlib.py
index 71c05b2..2b6fe7c 100644
--- a/pywikibot/textlib.py
+++ b/pywikibot/textlib.py
@@ -470,7 +470,7 @@
# On the other hand, this approach does not work because it
# can't handle lookahead or lookbehind (see bug T123185).
# So we have to process the group references manually.
- replacement = ''
+ replacement_parts = []
group_regex = re.compile(r'\\(\d+)|\\g<(.+?)>')
last = 0
@@ -480,13 +480,14 @@
group_id = int(group_id)
try:
- replacement += new[last:group_match.start()]
- replacement += match[group_id] or ''
+ replacement_parts.append(new[last:group_match.start()])
+ replacement_parts.append(match[group_id] or '')
except IndexError:
raise IndexError(f'Invalid group reference: {group_id}\n'
f'Groups found: {match.groups()}')
last = group_match.end()
- replacement += new[last:]
+ replacement_parts.append(new[last:])
+ replacement = ''.join(replacement_parts)
text = text[:match_start] + replacement + text[match.end():]
--
To view, visit
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1351448?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: Ia2cfa782412c78382d322b7c5baa7b01c51a3d6a
Gerrit-Change-Number: 1351448
Gerrit-PatchSet: 1
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]