jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1033606?usp=email )
Change subject: [doc] fix doc string with duplicate string entries
......................................................................
[doc] fix doc string with duplicate string entries
Change-Id: I511426ed8120796f7c1da97bfad10fa423aeb302
---
M pywikibot/tools/_deprecate.py
1 file changed, 6 insertions(+), 5 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/tools/_deprecate.py b/pywikibot/tools/_deprecate.py
index d8c56d3..9bbc133 100644
--- a/pywikibot/tools/_deprecate.py
+++ b/pywikibot/tools/_deprecate.py
@@ -174,7 +174,7 @@
`since`parameter must be a release number, not a timestamp.
:param instead: suggested replacement for the deprecated object
- :param since: a version string string when the method was deprecated
+ :param since: a version string when the method or function was deprecated
"""
if since and '.' not in since:
raise ValueError(f'{since} is not a valid release number')
@@ -204,7 +204,7 @@
:param depth: depth + 1 will be used as stacklevel for the warnings
:param warning_class: a warning class (category) to be used,
defaults to FutureWarning
- :param since: a version string string when the method was deprecated
+ :param since: a version string when the method or function was deprecated
"""
msg = _build_msg_string(instead, since)
if warning_class is None:
@@ -221,7 +221,7 @@
:keyword str instead: if provided, will be used to specify the
replacement
- :keyword str since: a version string string when the method was
+ :keyword str since: a version string when the method or function was
deprecated
:keyword bool future_warning: if True a FutureWarning will be thrown,
otherwise it provides a DeprecationWarning
@@ -525,7 +525,7 @@
new function.
:param class_name: The name of the class. It's added to the target and
source module (separated by a '.').
- :param since: a version string string when the method was deprecated
+ :param since: a version string when the method or function was deprecated
:param future_warning: if True a FutureWarning will be thrown,
otherwise it provides a DeprecationWarning
:return: A new function which adds a warning prior to each execution.
@@ -602,7 +602,8 @@
object name, and evaluated when the deprecated object is needed.
:param warning_message: The warning to display, with positional
variables: {0} = module, {1} = attribute name, {2} = replacement.
- :param since: a version string string when the method was deprecated
+ :param since: a version string when the method or function was
+ deprecated
:param future_warning: if True a FutureWarning will be thrown,
otherwise it provides a DeprecationWarning
"""
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1033606?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.wikimedia.org/r/settings
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: I511426ed8120796f7c1da97bfad10fa423aeb302
Gerrit-Change-Number: 1033606
Gerrit-PatchSet: 1
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged
jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1033192?usp=email )
Change subject: [fix] show the right docstring with tools.deprecated
......................................................................
[fix] show the right docstring with tools.deprecated
Previously the docstring of the outer wrapper of add_full_name
decorator was shown as the docstring of deprecated function.
Now remove the add_full_name when Sphinx is running.
Use the same technique with allow_asynchronous decorator.
Bug: T365286
Change-Id: I292bb7a3dc7a2804a77ce84dcf228848fc3239a4
---
M pywikibot/page/_decorators.py
M pywikibot/tools/_deprecate.py
2 files changed, 24 insertions(+), 21 deletions(-)
Approvals:
jenkins-bot: Verified
Xqt: Looks good to me, approved
diff --git a/pywikibot/page/_decorators.py b/pywikibot/page/_decorators.py
index 9108cc8..38c2d1f 100644
--- a/pywikibot/page/_decorators.py
+++ b/pywikibot/page/_decorators.py
@@ -1,6 +1,6 @@
"""Decorators for Page objects."""
#
-# (C) Pywikibot team, 2017-2022
+# (C) Pywikibot team, 2017-2024
#
# Distributed under the terms of the MIT license.
#
@@ -12,20 +12,17 @@
OtherPageSaveError,
PageSaveRelatedError,
)
-from pywikibot.tools import add_full_name, manage_wrapping
+from pywikibot.tools import SPHINX_RUNNING, add_full_name, manage_wrapping
-# decorating this function leads sphinx to hide it
-def _allow_asynchronous(func):
- """
- Decorator to make it possible to run a BasePage method asynchronously.
+def allow_asynchronous(func):
+ """Decorator to make it possible to run a BasePage method asynchronously.
- This is done when the method is called with kwarg asynchronous=True.
- Optionally, you can also provide kwarg callback, which, if provided, is
- a callable that gets the page as the first and a possible exception that
- occurred during saving in the second thread or None as the second argument.
-
- :meta public:
+ This is done when the method is called with kwarg
+ :code:`asynchronous=True`. Optionally, you can also provide kwarg
+ callback, which, if provided, is a callable that gets the page as
+ the first and a possible exception that occurred during saving in
+ the second thread or None as the second argument.
"""
def handle(func, self, *args, **kwargs):
do_async = kwargs.pop('asynchronous', False)
@@ -59,5 +56,6 @@
return wrapper
-#: `_allow_asynchronous` decorated with :func:`tools.add_full_name`
-allow_asynchronous = add_full_name(_allow_asynchronous)
+if not SPHINX_RUNNING:
+ # T365286: decorate allow_asynchronous function with add_full_name
+ allow_asynchronous = add_full_name(allow_asynchronous)
diff --git a/pywikibot/tools/_deprecate.py b/pywikibot/tools/_deprecate.py
index 58409ac..d8c56d3 100644
--- a/pywikibot/tools/_deprecate.py
+++ b/pywikibot/tools/_deprecate.py
@@ -36,6 +36,8 @@
from typing import Any
from warnings import warn
+from pywikibot.tools import SPHINX_RUNNING
+
class _NotImplementedWarning(RuntimeWarning):
@@ -211,20 +213,18 @@
warn(msg.format(name, instead), warning_class, depth + 1)
-@add_full_name
def deprecated(*args, **kwargs):
"""Decorator to output a deprecation warning.
.. versionchanged:: 7.0
`since` keyword must be a release number, not a timestamp.
- :keyword instead: if provided, will be used to specify the replacement
- :type instead: str
- :keyword since: a version string string when the method was deprecated
- :type since: str
- :keyword future_warning: if True a FutureWarning will be thrown,
+ :keyword str instead: if provided, will be used to specify the
+ replacement
+ :keyword str since: a version string string when the method was
+ deprecated
+ :keyword bool future_warning: if True a FutureWarning will be thrown,
otherwise it provides a DeprecationWarning
- :type future_warning: bool
"""
def decorator(obj):
"""Outer wrapper.
@@ -304,6 +304,11 @@
return decorator
+if not SPHINX_RUNNING:
+ # T365286: decorate deprecated function with add_full_name
+ deprecated = add_full_name(deprecated)
+
+
def deprecate_arg(old_arg: str, new_arg: str | bool | None):
"""Decorator to declare old_arg deprecated and replace it with new_arg.
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1033192?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.wikimedia.org/r/settings
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: I292bb7a3dc7a2804a77ce84dcf228848fc3239a4
Gerrit-Change-Number: 1033192
Gerrit-PatchSet: 1
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged
jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1033112?usp=email )
Change subject: [doc] Update ROADMAP.rst and CHANGELOG.rst
......................................................................
[doc] Update ROADMAP.rst and CHANGELOG.rst
Change-Id: I0cf875da1aff1f62797302e827715e35a25da5ce
---
M ROADMAP.rst
M scripts/CHANGELOG.rst
2 files changed, 5 insertions(+), 0 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/ROADMAP.rst b/ROADMAP.rst
index 7313b90..1bfeda5 100644
--- a/ROADMAP.rst
+++ b/ROADMAP.rst
@@ -1,11 +1,14 @@
Current release
---------------
+* Raise :exc:`exceptions.SectionError` if a section does not exists on a page (:phab:`T107141`)
* Retry api request on ServerError (:phab:`T364275`, :phab:`T364393`)
Deprecations
------------
+* 9.2.0: *total* argument in ``-logevents`` pagegenrators option is deprecated;
+ use ``-limit`` instead (:phab:`T128981`)
* 9.0.0: The *content* parameter of :meth:`proofreadpage.IndexPage.page_gen` is deprecated and will be ignored
(:phab:`T358635`)
* 9.0.0: ``userinterfaces.transliteration.transliterator`` was renamed to :class:`Transliterator
diff --git a/scripts/CHANGELOG.rst b/scripts/CHANGELOG.rst
index 334fac1..a7b5e4c 100644
--- a/scripts/CHANGELOG.rst
+++ b/scripts/CHANGELOG.rst
@@ -7,6 +7,8 @@
commons_information
^^^^^^^^^^^^^^^^^^^
+* Do not remove valid description parts of Information template (:phab:`T364640`)
+* Use transclusions of Information template as default generator
* Preload pages to make the script upto 10 times faster
noreferences
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1033112?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.wikimedia.org/r/settings
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: I0cf875da1aff1f62797302e827715e35a25da5ce
Gerrit-Change-Number: 1033112
Gerrit-PatchSet: 1
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: D3r1ck01 <dalangi-ctr(a)wikimedia.org>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged
jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1033102?usp=email )
Change subject: [doc] Update tests documentation
......................................................................
[doc] Update tests documentation
Change-Id: I4596f0f0702c43ad9efcdb0fcf73c75da1c9daca
---
M tests/aspects.py
M tests/setup_tests.py
M tests/thanks_tests.py
M tests/version_tests.py
4 files changed, 15 insertions(+), 20 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/tests/aspects.py b/tests/aspects.py
index 157210c..039542a 100644
--- a/tests/aspects.py
+++ b/tests/aspects.py
@@ -1288,17 +1288,19 @@
"""Test cases use :mod:`pwb` to invoke scripts.
- Test cases which use pwb typically also access a site, and use the network.
- Even during initialisation, scripts may call pywikibot.handle_args, which
- initialises loggers and uses the network to determine if the code is stale.
+ Test cases which use pwb typically also access a site, and use the
+ network. Even during initialisation, scripts may call
+ :func:`pywikibot.handle_args`, which initialises loggers and uses
+ the network to determine if the code is stale.
- The flag 'pwb' is used by the TestCase metaclass to check that a test site
- is set declared in the class properties, or that 'site = False' is added
- to the class properties in the unlikely scenario that the test case
- uses pwb in a way that doesn't use a site.
+ The flag 'pwb' is used by the TestCase metaclass to check that a
+ test site is set declared in the class properties, or that
+ :code:`site = False` is added to the class properties in the
+ unlikely scenario that the test case uses pwb in a way that doesn't
+ use a site.
- If a test class is marked as 'site = False', the metaclass will also check
- that the 'net' flag is explicitly set.
+ If a test class is marked as :code:`site = False , the metaclass
+ will also check that the ``net`` flag is explicitly set.
"""
pwb = True
diff --git a/tests/setup_tests.py b/tests/setup_tests.py
index 174aed5..8263f3a 100755
--- a/tests/setup_tests.py
+++ b/tests/setup_tests.py
@@ -1,8 +1,5 @@
#!/usr/bin/env python3
-"""Test setup.py.
-
-.. versionadded:: 9.0
-"""
+"""Test setup.py."""
#
# (C) Pywikibot team, 2024
#
diff --git a/tests/thanks_tests.py b/tests/thanks_tests.py
index 04b6fc9..19e5ca9 100755
--- a/tests/thanks_tests.py
+++ b/tests/thanks_tests.py
@@ -30,9 +30,8 @@
def test_thank_revision(self):
"""Test thanks for normal revisions.
- .. note:: This test relies on activity in recentchanges, and
- there must make edits made before reruns of this test.
- .. seealso:: :phab:`T137836`.
+ This test relies on activity in recentchanges, and there must
+ make edits made before reruns of this test; see :phab:`T137836`.
"""
site = self.get_site()
data = site.recentchanges(total=20)
diff --git a/tests/version_tests.py b/tests/version_tests.py
index 96a6de1..6da5b5d 100644
--- a/tests/version_tests.py
+++ b/tests/version_tests.py
@@ -1,8 +1,5 @@
#!/usr/bin/env python3
-"""Test cases for the :mod:`version` module.
-
-.. versionadded:: 9.2
-"""
+"""Test cases for the :mod:`version` module."""
#
# (C) Pywikibot team, 2024
#
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1033102?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.wikimedia.org/r/settings
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: I4596f0f0702c43ad9efcdb0fcf73c75da1c9daca
Gerrit-Change-Number: 1033102
Gerrit-PatchSet: 1
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged
jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1030201?usp=email )
Change subject: [bugfix] Do not remove valid description parts of Information template
......................................................................
[bugfix] Do not remove valid description parts of Information template
- use a set of lang codes instead ot the template pages; the comparison
is easier with that strings
- rewrite choosing language code in process_desc_template;
check whether the selected lang has a template page on wiki site
- add process_desc_other method to handle different nodes except
templates and comments
Bug: T364640
Change-Id: I960496f4f64839e9740180a47a3e89e348ff4b7d
---
M scripts/commons_information.py
1 file changed, 132 insertions(+), 57 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/scripts/commons_information.py b/scripts/commons_information.py
index e71aecd..2d5b31c 100755
--- a/scripts/commons_information.py
+++ b/scripts/commons_information.py
@@ -28,7 +28,7 @@
#
from __future__ import annotations
-import copy
+from textwrap import fill
import mwparserfromhell
@@ -62,7 +62,8 @@
"""Initialzer."""
super().__init__(**kwargs)
lang_tmp_cat = pywikibot.Category(self.site, self.lang_tmp_cat)
- self.lang_tmps = set(lang_tmp_cat.articles(namespaces=[10]))
+ self.lang_tmps = {t.title(with_ns=False).lower()
+ for t in lang_tmp_cat.articles(namespaces=[10])}
def get_description(self, template):
"""Get description parameter."""
@@ -75,50 +76,134 @@
return None
@staticmethod
- def detect_langs(text):
+ def detect_langs(text: str):
"""Detect language from given text."""
if langdetect is not None:
return langdetect.detect_langs(text)
return None
- def process_desc_template(self, template) -> bool:
- """Process description template."""
- tmp_page = pywikibot.Page(self.site, template.name.strip(), ns=10)
- if tmp_page in self.lang_tmps and len(template.params) == 1 \
+ def process_desc_template(
+ self,
+ template: mwparserfromhell.nodes.template.Template
+ ) -> bool:
+ """Process description template.
+
+ :param template: a mwparserfromhell Template found in the
+ description parameter of ``Information`` template.
+ :return: whether the *template* node was changed.
+ """
+ tmpl_lang = template.name.strip().lower()
+ if tmpl_lang in self.lang_tmps and len(template.params) == 1 \
and template.has('1'):
lang_tmp_val = template.get('1').value.strip()
langs = self.detect_langs(lang_tmp_val)
- if langs and langs[0].prob > 0.9:
- tmp_page2 = pywikibot.Page(self.site, langs[0].lang, ns=10)
- if tmp_page2 != tmp_page:
- pywikibot.info(
- '<<lightblue>>The language template {before!r} '
- 'was found, but langdetect thinks {after!r} is the '
- 'most appropriate with a probability of {prob}:'
- '<<default>>\n{text}'
- .format(before=tmp_page.title(with_ns=False),
- after=tmp_page2.title(with_ns=False),
- prob=langs[0].prob,
- text=lang_tmp_val))
+ if not langs:
+ return False
+
+ lang, prob = langs[0].lang, langs[0].prob
+ if lang != tmpl_lang and prob > 0.9 and lang in self.lang_tmps:
+ pywikibot.info(
+ f'<<lightblue>>The language template {tmpl_lang!r} '
+ f'was found, but language detection thinks {lang!r}\n'
+ f'is the most appropriate with a probability of {prob}:'
+ )
+ pywikibot.info(fill(lang_tmp_val, width=78))
+ while True:
choice = pywikibot.input_choice(
'What to do?',
- [('Replace it', 'r'), ('Do not replace it', 'n'),
- ('Choose another', 'c')])
+ [
+ ('Replace it', 'r'),
+ ('Do not replace it', 'n'),
+ ('Choose another', 'c'),
+ ],
+ default='n',
+ )
+ if choice == 'n':
+ break
+
if choice == 'r':
- template.name = langs[0].lang
+ template.name = lang
return True
- if choice == 'c':
- newlang = pywikibot.input(
- 'Enter the language of the displayed text:')
- if newlang and newlang != template.name:
- template.name = newlang
- return True
+ # choice == 'c':
+ newlang = pywikibot.input(
+ 'Enter the language of the displayed text:').strip()
+ if not newlang or newlang == tmpl_lang:
+ break
+
+ if newlang in self.lang_tmps:
+ template.name = newlang
+ return True
+
+ pywikibot.warning(f'<<lightred>>{newlang!r} is not a valid'
+ f' language template on {self.site}')
return False
+ def process_desc_other(self,
+ wikicode: mwparserfromhell.wikicode.Wikicode,
+ nodes: list[mwparserfromhell.nodes.Node]) -> bool:
+ """Process other description text.
+
+ The description text may consist of different Node types except
+ of Template which is handled by :meth:`process_desc_template`.
+ Combine all nodes and replace the last with new created
+ Template while removing the remaining from *wikicode*.
+
+ .. versionadded:: 9.2
+
+ :param wikicode: The Wikicode of the parsed page text.
+ :param nodes: wikitext nodes to be processed
+ :return: whether the description nodes were changed
+ """
+ if type(nodes[0]).__name__ == 'Text' and nodes[0].value.isspace():
+ # ignore the first node with spaces only
+ nodes = nodes[1:]
+
+ value = ''.join(str(node) for node in nodes).strip()
+ if not value:
+ return False
+
+ pywikibot.info(fill(value, 78))
+ langs = self.detect_langs(value)
+
+ if langs:
+ pywikibot.info('<<lightblue>>Hints from langdetect:')
+ for language in langs:
+ pywikibot.info(
+ f'<<lightblue>>{language.lang}: {language.prob}')
+
+ while True:
+ lang = pywikibot.input(
+ 'Enter the language of the displayed text:').strip()
+
+ if not lang:
+ return False
+
+ if lang in self.lang_tmps:
+ break
+
+ pywikibot.warning(f'<<lightred>>{lang!r} is not a valid language '
+ f'template on {self.site}')
+
+ # replace the last node
+ new = mwparserfromhell.nodes.template.Template(lang, [value.rstrip()])
+ try:
+ self.replace_value(nodes[-1], new)
+ except AttributeError:
+ # Node is has no value attribute, add the template directly
+ wikicode.insert_after(nodes[-1], str(new))
+ wikicode.remove(nodes[-1])
+
+ # remove the other nodes
+ for node in nodes[:-1]:
+ node = wikicode.remove(node)
+
+ return True
+
@staticmethod
- def replace_value(param, value) -> None:
- """Replace param with given value."""
+ def replace_value(param: mwparserfromhell.nodes.Node,
+ value: mwparserfromhell.nodes.template.Template) -> None:
+ """Replace *param* node with given value."""
lstrip = param.value.lstrip()
lspaces = param.value[:len(param.value) - len(lstrip)]
rspaces = lstrip[len(lstrip.rstrip()):]
@@ -138,37 +223,27 @@
if desc is None:
continue
- for tmp in desc.value.filter_templates(recursive=False):
- if self.process_desc_template(tmp):
- edited = True
+ unhandled = []
+ for node in desc.value.nodes:
+ node_type = type(node).__name__
- desc_clean = copy.deepcopy(desc.value)
- for tmp in desc_clean.filter_templates(recursive=False):
- # TODO: emit a debug item?
- desc_clean.remove(tmp)
+ if node_type == 'Comment':
+ pass
+ elif node_type == 'Template':
- value = desc_clean.strip()
- if value == '':
- pywikibot.info('Empty description')
- continue
+ # first handle unhandled nodes
+ if unhandled:
+ if self.process_desc_other(code, unhandled):
+ edited = True
+ unhandled = []
- pywikibot.info(value)
- langs = self.detect_langs(value)
- if langs:
- pywikibot.info('<<lightblue>>Hints from langdetect:')
- for language in langs:
- pywikibot.info(
- f'<<lightblue>>{language.lang}: {language.prob}')
+ # now process hte template
+ if self.process_desc_template(node):
+ edited = True
+ else:
+ unhandled.append(node)
- lang = pywikibot.input(
- 'Enter the language of the displayed text:').strip()
- if lang != '':
- tmp_page = pywikibot.Page(page.site, lang, ns=10)
- if tmp_page not in self.lang_tmps:
- pywikibot.warning(f'{lang!r} is not a valid language '
- f'template on {page.site}')
- new = mwparserfromhell.nodes.template.Template(lang, [value])
- self.replace_value(desc, new)
+ if unhandled and self.process_desc_other(code, unhandled):
edited = True
if edited:
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1030201?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.wikimedia.org/r/settings
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: I960496f4f64839e9740180a47a3e89e348ff4b7d
Gerrit-Change-Number: 1030201
Gerrit-PatchSet: 7
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: D3r1ck01 <dalangi-ctr(a)wikimedia.org>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged
jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1030531?usp=email )
Change subject: [IMPR] use transclusions of Information template as default generator
......................................................................
[IMPR] use transclusions of Information template as default generator
- if no generator is given, use file transclusions of Information templates
- use commons:commons as default site
- update documentation
Change-Id: I3fa02ce47007635c8c8caa99119494553d685668
---
M scripts/commons_information.py
1 file changed, 62 insertions(+), 14 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/scripts/commons_information.py b/scripts/commons_information.py
index e71aecd..415cbfa 100755
--- a/scripts/commons_information.py
+++ b/scripts/commons_information.py
@@ -1,6 +1,38 @@
#!/usr/bin/env python3
-"""
-This bot adds a language template to the file's description field.
+"""This bot adds a language template to the file's description field.
+
+The ``Information`` template is commonly used to provide formatting to
+the basic information for files (description, source, author, etc.). The
+``description`` field should provide brief but complete information
+about the image. The description format should use Language templates
+like ``{{En}}`` or ``{{De}}`` to specify the language of the description.
+This script adds these langage templates if missing. For example the
+description of
+
+.. code-block:: wikitext
+
+ {{Information
+ | Description = A simplified icon for [[Pywikibot]]
+ | Date = 2003-06-14
+ | Other fields =
+ }}
+
+will be analyzed as ``en`` language by ~100 % accurancy and the bot
+replaces its content by
+
+.. code-block:: wikitext
+ :emphasize-lines: 2
+
+ {{Information
+ | Description = {{en|A simplified icon for [[Pywikibot]]}}
+ | Date = 2003-06-14
+ | Other fields =
+ }}
+
+.. note:: ``langdetect`` package is needed for fully support of language
+ detection. Install it with::
+
+ pip install langdetect
This script understands the following command-line arguments:
@@ -10,8 +42,12 @@
python pwb.py commons_information [pagegenerators]
-You can use any typical pagegenerator (like categories) to provide with a
-list of pages.
+You can use any typical pagegenerator (like categories) to provide with
+a list of pages. If no pagegenerator is given, transcluded pages from
+``Information`` template are used.
+
+.. hint:: This script uses ``commons`` site as default. For other sites
+ use the global ``-site`` option.
Example for going through all files:
@@ -19,7 +55,8 @@
.. versionadded:: 6.0
.. versionchanged:: 9.2
- accelerated script with preloading pages.
+ accelerate script with preloading pages; use ``commons`` as default
+ site; use transcluded pages of ``Information`` template.
"""
#
# (C) Pywikibot team, 2015-2024
@@ -33,7 +70,7 @@
import mwparserfromhell
import pywikibot
-from pywikibot import i18n, pagegenerators
+from pywikibot import config, i18n, pagegenerators
from pywikibot.bot import ExistingPageBot, SingleSiteBot
# This is required for the text that is shown when you run this script
@@ -46,6 +83,9 @@
langdetect = None
+INFORMATION_TMPL = 'Information'
+
+
class InformationBot(SingleSiteBot, ExistingPageBot):
"""Bot for the Information template."""
@@ -54,8 +94,8 @@
desc_params = ('Description', 'description')
comment = {
- 'en': ('Bot: wrap the description parameter of Information in the '
- 'appropriate language template')
+ 'en': (f'Bot: wrap the description parameter of {INFORMATION_TMPL} in'
+ ' the appropriate language template')
}
def __init__(self, **kwargs) -> None:
@@ -131,7 +171,8 @@
edited = False # to prevent unwanted changes
for template in code.ifilter_templates():
- if not page.site.sametitle(template.name.strip(), 'Information'):
+ if not page.site.sametitle(template.name.strip(),
+ INFORMATION_TMPL):
continue
desc = self.get_description(template)
@@ -186,18 +227,25 @@
:param args: command line arguments
"""
+ # set default family to commons
+ config.mylang = config.family = 'commons'
+
local_args = pywikibot.handle_args(args)
gen_factory = pagegenerators.GeneratorFactory()
for arg in local_args:
gen_factory.handle_arg(arg)
+ site = pywikibot.Site()
gen = gen_factory.getCombinedGenerator(preload=True)
- if gen:
- bot = InformationBot(generator=gen)
- bot.run()
- else:
- pywikibot.bot.suggest_help(missing_generator=True)
+ if not gen:
+ tmpl = pywikibot.Page(site, INFORMATION_TMPL,
+ ns=site.namespaces.TEMPLATE)
+ gen = tmpl.getReferences(only_template_inclusion=True,
+ namespaces=site.namespaces.FILE,
+ content=True)
+ bot = InformationBot(site=site, generator=gen)
+ bot.run()
if __name__ == '__main__':
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1030531?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.wikimedia.org/r/settings
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: I3fa02ce47007635c8c8caa99119494553d685668
Gerrit-Change-Number: 1030531
Gerrit-PatchSet: 1
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: D3r1ck01 <dalangi-ctr(a)wikimedia.org>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged
jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1030049?usp=email )
Change subject: [fix] raise SectionError if a section does not exists on a page
......................................................................
[fix] raise SectionError if a section does not exists on a page
Also add some tests and update documentation.
Bug: T107141
Change-Id: Ib515e94657e7100695b69d77934d448ce424e232
---
M pywikibot/page/_basepage.py
M tests/page_tests.py
2 files changed, 38 insertions(+), 6 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/page/_basepage.py b/pywikibot/page/_basepage.py
index 8eaeeb0..1c51f20 100644
--- a/pywikibot/page/_basepage.py
+++ b/pywikibot/page/_basepage.py
@@ -292,11 +292,10 @@
return title
def section(self) -> str | None:
- """
- Return the name of the section this Page refers to.
+ """Return the name of the section this Page refers to.
- The section is the part of the title following a '#' character, if
- any. If no section is present, return None.
+ The section is the part of the title following a ``#`` character,
+ if any. If no section is present, return None.
"""
try:
section = self._link.section
@@ -373,12 +372,14 @@
...
pywikibot.exceptions.IsRedirectPageError: ... is a redirect page.
+ .. versionchanged:: 9.2
+ :exc:`exceptions.SectionError` is raised if the
+ :meth:`section` does not exists
.. seealso:: :attr:`text` property
:param force: reload all page attributes, including errors.
:param get_redirect: return the redirect text, do not follow the
redirect, do not raise an exception.
-
:raises NoPageError: The page does not exist.
:raises IsRedirectPageError: The page is a redirect.
:raises SectionError: The section does not exist on a page with
@@ -394,7 +395,18 @@
if not get_redirect:
raise
- return self.latest_revision.text # type: ignore[attr-defined]
+ text = self.latest_revision.text
+
+ # check for valid section in title
+ page_section = self.section()
+ if page_section:
+ content = textlib.extract_sections(text, self.site)
+ headings = {section.heading for section in content.sections}
+ if page_section not in headings:
+ raise SectionError(f'{page_section!r} is not a valid section '
+ f'of {self.title(with_section=False)}')
+
+ return text
def has_content(self) -> bool:
"""
diff --git a/tests/page_tests.py b/tests/page_tests.py
index b56cf4b..ea4dfd8 100755
--- a/tests/page_tests.py
+++ b/tests/page_tests.py
@@ -22,6 +22,7 @@
IsNotRedirectPageError,
IsRedirectPageError,
NoPageError,
+ SectionError,
TimeoutError,
UnknownExtensionError,
)
@@ -974,6 +975,7 @@
def testPageGet(self):
"""Test ``Page.get()`` on different types of pages."""
+ fail_msg = '{page!r}.get() raised {error!r} unexpectedly!'
site = self.get_site('en')
p1 = pywikibot.Page(site, 'User:Legoktm/R2')
p2 = pywikibot.Page(site, 'User:Legoktm/R1')
@@ -986,9 +988,27 @@
r'{} is a redirect page\.'
.format(re.escape(str(p2)))):
p2.get()
+
+ try:
+ p2.get(get_redirect=True)
+ except (IsRedirectPageError, NoPageError, SectionError) as e:
+ self.fail(fail_msg.format(page=p2, error=e))
+
with self.assertRaisesRegex(NoPageError, NO_PAGE_RE):
p3.get()
+ page = pywikibot.Page(site, 'User:Legoktm/R2#Section')
+ with self.assertRaisesRegex(SectionError,
+ "'Section' is not a valid section"):
+ page.get()
+
+ site = pywikibot.Site('mediawiki')
+ page = pywikibot.Page(site, 'Manual:Pywikibot/2.0 #See_also')
+ try:
+ page.get()
+ except (IsRedirectPageError, NoPageError, SectionError) as e:
+ self.fail(fail_msg.format(page=page, error=e))
+
def test_set_redirect_target(self):
"""Test set_redirect_target method."""
# R1 redirects to R2 and R3 doesn't exist.
--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1030049?usp=email
To unsubscribe, or for help writing mail filters, visit https://gerrit.wikimedia.org/r/settings
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: Ib515e94657e7100695b69d77934d448ce424e232
Gerrit-Change-Number: 1030049
Gerrit-PatchSet: 3
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged