jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1181291?usp=email )
Change subject: tests: enable global options in script_tests
......................................................................
tests: enable global options in script_tests
script_tests calls pwb with script and local args, but the given
global options weren't taken. Now global arguments are saved in
bot.global_args and reused within script_tests.
Bug: T250034
Change-Id: Ibaf8ab0a58aa68417b4b0e6006ac0fd3ca8ac251
---
M pywikibot/bot.py
M tests/script_tests.py
2 files changed, 8 insertions(+), 1 deletion(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/bot.py b/pywikibot/bot.py
index 3ed0611..9aab5c2 100644
--- a/pywikibot/bot.py
+++ b/pywikibot/bot.py
@@ -278,6 +278,9 @@
"""Holds a user interface object defined in :mod:`pywikibot.userinterfaces`
subpackage."""
+#: global args used by tests via pwb wrapper
+global_args: list[str] | None = None
+
def set_interface(module_name: str) -> None:
"""Configures any bots to use the given interface module.
@@ -749,6 +752,9 @@
# not the one in pywikibot.bot.
args = pywikibot.argvu[1:]
+ global global_args
+ global_args = args
+
# get the name of the module calling this function. This is
# required because the -help option loads the module's docstring and
# because the module name will be used for the filename of the log.
diff --git a/tests/script_tests.py b/tests/script_tests.py
index 6c0128c..356c6df 100755
--- a/tests/script_tests.py
+++ b/tests/script_tests.py
@@ -14,6 +14,7 @@
from pathlib import Path
from pywikibot.backports import Iterator
+from pywikibot.bot import global_args as pwb_args
from pywikibot.tools import has_module
from tests import join_root_path, unittest_print
from tests.aspects import DefaultSiteTestCase, MetaTestCaseClass, PwbTestCase
@@ -212,7 +213,7 @@
def test_script(self) -> None:
global_args_msg = \
'For global options use -help:global or run pwb'
- global_args = ['-pwb_close_matches:1']
+ global_args = (pwb_args or []) + ['-pwb_close_matches:1']
cmd = [*global_args, script_name, *args]
data_in = script_input.get(script_name)
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1181291?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: Ibaf8ab0a58aa68417b4b0e6006ac0fd3ca8ac251
Gerrit-Change-Number: 1181291
Gerrit-PatchSet: 2
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot
jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1181286?usp=email )
Change subject: tests: do not exclude failed dependencies for TestScriptHelp
......................................................................
tests: do not exclude failed dependencies for TestScriptHelp
Bug: T276466
Change-Id: Iaf4dbe26da52555e5f5b7460e4aa6746b7602e2f
---
M tests/script_tests.py
1 file changed, 8 insertions(+), 6 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/tests/script_tests.py b/tests/script_tests.py
index bc2b346..4827742 100755
--- a/tests/script_tests.py
+++ b/tests/script_tests.py
@@ -38,8 +38,6 @@
if script_name in script_deps:
for package_name in script_deps[script_name]:
if not has_module(package_name):
- unittest_print(f'{script_name} depends on {package_name},'
- " which isn't available")
return False
return True
@@ -167,11 +165,15 @@
def filter_scripts(excluded: set[str] | None = None, *,
- exclude_auto_run: bool = False) -> list[str]:
+ exclude_auto_run: bool = False,
+ exclude_failed_dep: bool = True) -> list[str]:
"""Return a filtered list of script names.
:param excluded: Scripts to exclude explicitly.
- :param exclude_auto_run: If True, remove scripts in auto_run_script_set.
+ :param exclude_auto_run: If True, remove scripts in
+ auto_run_script_set.
+ :param exclude_failed_dep: If True, remove scripts in
+ failed_dep_script_set.
:return: A list of valid script names in deterministic order.
"""
excluded = excluded or set()
@@ -180,7 +182,7 @@
name for name in sorted(script_list)
if name != 'login'
and name not in unrunnable_script_set
- and name not in failed_dep_script_set
+ and (not exclude_failed_dep or name not in failed_dep_script_set)
]
if exclude_auto_run:
@@ -329,7 +331,7 @@
_results = None
_skip_results = {}
_timeout = False
- _script_list = filter_scripts()
+ _script_list = filter_scripts(exclude_failed_dep=False)
class TestScriptSimulate(DefaultSiteTestCase, PwbTestCase,
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1181286?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: Iaf4dbe26da52555e5f5b7460e4aa6746b7602e2f
Gerrit-Change-Number: 1181286
Gerrit-PatchSet: 2
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot
Xqt has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1181285?usp=email )
Change subject: tests: refactor script test loading and filtering
......................................................................
tests: refactor script test loading and filtering
This patch synchronizes the script tests of `TestClass` and `TestSuite`.
- Introduce `filter_scripts()` to centralize script selection and
remove redundant filtering logic.
- Replace previous collector logic with a simple generator using
`_script_names` from each test class.
- Remove metaclass reliance on hard-coded script lists; classes
now get `_script_list` populated via `filter_scripts()`.
Change-Id: Ie95ff04c7a7ed91da193aff2a043c1c54a2da7f8
---
M tests/script_tests.py
1 file changed, 40 insertions(+), 39 deletions(-)
Approvals:
jenkins-bot: Verified
Xqt: Looks good to me, approved
diff --git a/tests/script_tests.py b/tests/script_tests.py
index d1f635b..bc2b346 100755
--- a/tests/script_tests.py
+++ b/tests/script_tests.py
@@ -150,42 +150,45 @@
def collector() -> Iterator[str]:
- """Generate test names in the correct order, respecting filters."""
- base_tests = ['_login'] + [
- name for name in sorted(script_list)
- if name != 'login'
- # Exclude scripts that cannot or should not run
- and name not in unrunnable_script_set
- # Exclude scripts that fail due to missing dependencies
- and name not in failed_dep_script_set
- ]
-
- # Build filtered test lists per class
- class_to_tests = {
- TestScriptHelp: base_tests,
- TestScriptSimulate: base_tests,
- TestScriptGenerator: [
- name for name in base_tests if name not in auto_run_script_set
- ]
- }
-
- # Yield fully qualified test names, skipping expected failures
- for cls, names in class_to_tests.items():
- expected_failures = getattr(cls, '_expected_failures', set())
- for name in names:
- if name not in expected_failures:
- yield f'tests.script_tests.{cls.__name__}.test_{name}'
+ """Generate test fully qualified names from test classes."""
+ for cls in TestScriptHelp, TestScriptSimulate, TestScriptGenerator:
+ for name in cls._script_list:
+ name = '_' + name if name == 'login' else name
+ yield f'tests.script_tests.{cls.__name__}.test_{name}'
def load_tests(loader: unittest.TestLoader = unittest.defaultTestLoader,
- standard_tests=None,
- pattern=None) -> unittest.TestSuite:
+ standard_tests: unittest.TestSuite | None = None,
+ pattern: str | None = None) -> unittest.TestSuite:
"""Load the default modules and return a TestSuite."""
suite = unittest.TestSuite()
suite.addTests(loader.loadTestsFromNames(collector()))
return suite
+def filter_scripts(excluded: set[str] | None = None, *,
+ exclude_auto_run: bool = False) -> list[str]:
+ """Return a filtered list of script names.
+
+ :param excluded: Scripts to exclude explicitly.
+ :param exclude_auto_run: If True, remove scripts in auto_run_script_set.
+ :return: A list of valid script names in deterministic order.
+ """
+ excluded = excluded or set()
+
+ scripts = ['login'] + [
+ name for name in sorted(script_list)
+ if name != 'login'
+ and name not in unrunnable_script_set
+ and name not in failed_dep_script_set
+ ]
+
+ if exclude_auto_run:
+ scripts = [n for n in scripts if n not in auto_run_script_set]
+
+ return [n for n in scripts if n not in excluded]
+
+
class ScriptTestMeta(MetaTestCaseClass):
"""Test meta class."""
@@ -291,24 +294,19 @@
arguments = dct['_arguments']
- for script_name in script_list:
+ for script in dct['_script_list']:
# force login to be the first, alphabetically, so the login
# message does not unexpectedly occur during execution of
# another script.
- # unrunnable script tests are disabled by default in load_tests()
+ test = 'test__login' if script == 'login' else 'test_' + script
- if script_name == 'login':
- test_name = 'test__login'
- else:
- test_name = 'test_' + script_name
+ cls.add_method(dct, test,
+ test_execution(script, arguments.split()),
+ f'Test running {script} {arguments}.')
- cls.add_method(dct, test_name,
- test_execution(script_name, arguments.split()),
- f'Test running {script_name} {arguments}.')
-
- if script_name in dct['_expected_failures']:
- dct[test_name] = unittest.expectedFailure(dct[test_name])
+ if script in dct['_expected_failures']:
+ dct[test] = unittest.expectedFailure(dct[test])
return super().__new__(cls, name, bases, dct)
@@ -331,6 +329,7 @@
_results = None
_skip_results = {}
_timeout = False
+ _script_list = filter_scripts()
class TestScriptSimulate(DefaultSiteTestCase, PwbTestCase,
@@ -379,6 +378,7 @@
_results = no_args_expected_results
_skip_results = skip_on_results
_timeout = auto_run_script_set
+ _script_list = filter_scripts(_allowed_failures)
class TestScriptGenerator(DefaultSiteTestCase, PwbTestCase,
@@ -446,6 +446,7 @@
_results = ("Working on 'Foobar'", 'Script terminated successfully')
_skip_results = {}
_timeout = True
+ _script_list = filter_scripts(_allowed_failures, exclude_auto_run=True)
if __name__ == '__main__':
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1181285?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: Ie95ff04c7a7ed91da193aff2a043c1c54a2da7f8
Gerrit-Change-Number: 1181285
Gerrit-PatchSet: 2
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot
Xqt has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/959820?usp=email )
Change subject: [tests] Speedup script_tests
......................................................................
[tests] Speedup script_tests
Do not create a test method if script is in _allowed_failures;
such scripts may or may not fail and it does not make any sense
to create the test method and use a @skip decorator to skip it.
Change-Id: I67ef4433513b4d51756517fe3006fc04529ac7c3
---
M tests/script_tests.py
1 file changed, 30 insertions(+), 35 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/tests/script_tests.py b/tests/script_tests.py
index 4ff8fd2..d1f635b 100755
--- a/tests/script_tests.py
+++ b/tests/script_tests.py
@@ -13,6 +13,7 @@
from contextlib import suppress
from pathlib import Path
+from pywikibot.backports import Iterator
from pywikibot.tools import has_module
from tests import join_root_path, unittest_print
from tests.aspects import DefaultSiteTestCase, MetaTestCaseClass, PwbTestCase
@@ -148,40 +149,43 @@
}
-def collector(loader=unittest.loader.defaultTestLoader):
- """Load the default tests.
+def collector() -> Iterator[str]:
+ """Generate test names in the correct order, respecting filters."""
+ base_tests = ['_login'] + [
+ name for name in sorted(script_list)
+ if name != 'login'
+ # Exclude scripts that cannot or should not run
+ and name not in unrunnable_script_set
+ # Exclude scripts that fail due to missing dependencies
+ and name not in failed_dep_script_set
+ ]
- .. note:: Raising SkipTest during load_tests will cause the loader
- to fallback to its own discover() ordering of unit tests.
- """
- if unrunnable_script_set: # pragma: no cover
- unittest_print('Skipping execution of unrunnable scripts:\n'
- f'{unrunnable_script_set!r}')
+ # Build filtered test lists per class
+ class_to_tests = {
+ TestScriptHelp: base_tests,
+ TestScriptSimulate: base_tests,
+ TestScriptGenerator: [
+ name for name in base_tests if name not in auto_run_script_set
+ ]
+ }
- test_pattern = 'tests.script_tests.TestScript{}.test_{}'
+ # Yield fully qualified test names, skipping expected failures
+ for cls, names in class_to_tests.items():
+ expected_failures = getattr(cls, '_expected_failures', set())
+ for name in names:
+ if name not in expected_failures:
+ yield f'tests.script_tests.{cls.__name__}.test_{name}'
- tests = ['_login'] + [name for name in sorted(script_list)
- if name != 'login'
- and name not in unrunnable_script_set]
- test_list = [test_pattern.format('Help', name) for name in tests]
- tests = [name for name in tests if name not in failed_dep_script_set]
- test_list += [test_pattern.format('Simulate', name) for name in tests]
-
- tests = [name for name in tests if name not in auto_run_script_set]
- test_list += [test_pattern.format('Generator', name) for name in tests]
-
+def load_tests(loader: unittest.TestLoader = unittest.defaultTestLoader,
+ standard_tests=None,
+ pattern=None) -> unittest.TestSuite:
+ """Load the default modules and return a TestSuite."""
suite = unittest.TestSuite()
- suite.addTests(loader.loadTestsFromNames(test_list))
+ suite.addTests(loader.loadTestsFromNames(collector()))
return suite
-def load_tests(loader=unittest.loader.defaultTestLoader,
- tests=None, pattern=None):
- """Load the default modules."""
- return collector(loader)
-
-
class ScriptTestMeta(MetaTestCaseClass):
"""Test meta class."""
@@ -305,15 +309,6 @@
if script_name in dct['_expected_failures']:
dct[test_name] = unittest.expectedFailure(dct[test_name])
- elif script_name in dct['_allowed_failures']:
- dct[test_name] = unittest.skip(
- f'{script_name} is in _allowed_failures set'
- )(dct[test_name])
- elif script_name in failed_dep_script_set \
- and arguments == '-simulate':
- dct[test_name] = unittest.skip(
- f'{script_name} has dependencies; skipping'
- )(dct[test_name])
return super().__new__(cls, name, bases, dct)
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/959820?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: I67ef4433513b4d51756517fe3006fc04529ac7c3
Gerrit-Change-Number: 959820
Gerrit-PatchSet: 9
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot
jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1179258?usp=email )
Change subject: [fixes] Improve parameter_help formatting and _load_file readability
......................................................................
[fixes] Improve parameter_help formatting and _load_file readability
- parameter_help: improve wording for CLI help output
- _load_file: use pathlib for modern path handling and clarify docstring
Change-Id: I2ecc278de04339961ecc6a8f851f45be1e6d1ba7
---
M pywikibot/fixes.py
1 file changed, 30 insertions(+), 24 deletions(-)
Approvals:
jenkins-bot: Verified
Xqt: Looks good to me, approved
diff --git a/pywikibot/fixes.py b/pywikibot/fixes.py
index db65059..684850c 100644
--- a/pywikibot/fixes.py
+++ b/pywikibot/fixes.py
@@ -1,18 +1,18 @@
"""File containing all standard fixes."""
#
-# (C) Pywikibot team, 2008-2022
+# (C) Pywikibot team, 2008-2025
#
# Distributed under the terms of the MIT license.
#
from __future__ import annotations
-import os.path
+from pathlib import Path
from pywikibot import config
parameter_help = """
- Currently available predefined fixes are:
+ Currently available predefined fixes:
* HTML - Convert HTML tags to wiki syntax, and
fix XHTML.
@@ -20,21 +20,20 @@
* syntax - Try to fix bad wiki markup. Do not run
this in automatic mode, as the bot may
make mistakes.
- * syntax-safe - Like syntax, but less risky, so you can
- run this in automatic mode.
- * case-de - fix upper/lower case errors in German
- * grammar-de - fix grammar and typography in German
- * vonbis - Ersetze Binde-/Gedankenstrich durch "bis"
- in German
- * music - Links auf Begriffsklärungen in German
- * datum - specific date formats in German
- * correct-ar - Typo corrections for Arabic Wikipedia and any
- Arabic wiki.
- * yu-tld - Fix links to .yu domains because it is
- disabled, see:
+ * syntax-safe - Like syntax, but less risky; can be run
+ in automatic mode.
+ * case-de - Fix upper/lower case errors in German.
+ * grammar-de - Fix grammar and typography in German.
+ * vonbis - Replace hyphens or dashes with "bis"
+ in German.
+ * music - Links to disambiguation pages in German.
+ * datum - Specific date formats in German.
+ * correct-ar - Typo corrections for Arabic Wikipedia
+ and other Arabic wikis.
+ * yu-tld - Fix links to .yu domains, which are disabled.
+ See:
https://lists.wikimedia.org/pipermail/wikibots-l/2009-February/000290.html
- * fckeditor - Try to convert FCKeditor HTML tags to wiki
- syntax.
+ * fckeditor - Convert FCKeditor HTML tags to wiki syntax.
"""
__doc__ += parameter_help
@@ -673,20 +672,27 @@
'msg': 'pywikibot-fixes-fckeditor',
'replacements': [
# replace <br> with a new line
- (r'(?i)<br>', r'\n'),
+ (r'(?i)<br>', r'\n'),
# replace with a space
- (r'(?i) ', r' '),
+ (r'(?i) ', r' '),
],
},
}
def _load_file(filename: str) -> bool:
- """Load the fixes from the given filename."""
- if os.path.exists(filename):
- # load binary, to let compile decode it according to the file header
- with open(filename, 'rb') as f:
- exec(compile(f.read(), filename, 'exec'), globals())
+ """Load the fixes from the given filename.
+
+ Returns True if the file existed and was loaded, False otherwise.
+
+ :meta public:
+ """
+ path = Path(filename)
+ if path.exists():
+ # Read file as binary, so that compile can detect encoding from header
+ with path.open('rb') as f:
+ code = compile(f.read(), filename, 'exec')
+ exec(code, globals()) # intentionally in globals
return True
return False
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1179258?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: I2ecc278de04339961ecc6a8f851f45be1e6d1ba7
Gerrit-Change-Number: 1179258
Gerrit-PatchSet: 3
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot
jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/i18n/+/1181234?usp=email )
Change subject: i18n: Remove 'category_redirect-log-move-error' translations from Pywikibot
......................................................................
i18n: Remove 'category_redirect-log-move-error' translations from Pywikibot
The 'category_redirect-log-move-error' translation was removed
in rPWBC576a51bd1cf5 with release 7.0 and is no longer needed.
Bug: T300429
Change-Id: Iee521d91470619e08fc1b735db73fbb9fce32fe7
---
M category_redirect/en.json
M category_redirect/qqq.json
2 files changed, 0 insertions(+), 2 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/category_redirect/en.json b/category_redirect/en.json
index 9926e15..35cf629 100644
--- a/category_redirect/en.json
+++ b/category_redirect/en.json
@@ -17,7 +17,6 @@
"category_redirect-log-false-positive": "* Unexpected non-redirect: %(oldcat)s",
"category_redirect-log-ignoring": "* Ignoring %(oldcat)s",
"category_redirect-log-loop": "* Redirect loop from %(oldcat)s",
- "category_redirect-log-move-error": "* %(oldcat)s: error in move_contents",
"category_redirect-log-moved": "* %(oldcat)s: %(found)d found, %(moved)d moved",
"category_redirect-log-new": "New redirects since last report:",
"category_redirect-log-not-loaded": "* Could not load %(oldcat)s; ignoring",
diff --git a/category_redirect/qqq.json b/category_redirect/qqq.json
index a2b36be..c8519c5 100644
--- a/category_redirect/qqq.json
+++ b/category_redirect/qqq.json
@@ -21,7 +21,6 @@
"category_redirect-log-false-positive": "Log message indicating category page was not redirect.",
"category_redirect-log-ignoring": "Log message indicating category page is a redirect on purpose.",
"category_redirect-log-loop": "Log message indicating category redirect chain makes a loop.",
- "category_redirect-log-move-error": "Log message indicating category contents could not be moved.",
"category_redirect-log-moved": "Log message indicating pages found and moved from the redirected category.",
"category_redirect-log-new": "Log page heading",
"category_redirect-log-not-loaded": "Log message indicating category page could not be loaded.",
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/i18n/+/1181234?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/i18n
Gerrit-Branch: master
Gerrit-Change-Id: Iee521d91470619e08fc1b735db73fbb9fce32fe7
Gerrit-Change-Number: 1181234
Gerrit-PatchSet: 1
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot