jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/775347 )
Change subject: [IMPR] Deprecate RedirectPageBot and NoRedirectPageBot ......................................................................
[IMPR] Deprecate RedirectPageBot and NoRedirectPageBot
Instead of having multiple classes to determine the pages to be processed, just use an attribute. As first step deprecate RedirectPageBot and NoRedirectPageBot and use 'use-redirects' attribute instead.
Change-Id: Ibbc97a3ade4c04e881afcd7a27e631197f0db730 --- M pywikibot/bot.py M pywikibot/specialbots/_unlink.py M scripts/add_text.py M scripts/basic.py M scripts/commonscat.py M scripts/cosmetic_changes.py M scripts/fixing_redirects.py M scripts/newitem.py M scripts/noreferences.py M scripts/parser_function_count.py M scripts/redirect.py M scripts/reflinks.py 12 files changed, 107 insertions(+), 69 deletions(-)
Approvals: DannyS712: Looks good to me, but someone else must approve Xqt: Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/bot.py b/pywikibot/bot.py index 7401883..b70f2f3 100644 --- a/pywikibot/bot.py +++ b/pywikibot/bot.py @@ -1202,28 +1202,39 @@ """ Generic Bot to be subclassed.
- This class provides a run() method for basic processing of a + This class provides a :meth:`run` method for basic processing of a generator one page at a time.
- If the subclass places a page generator in self.generator, - Bot will process each page in the generator, invoking the method treat() - which must then be implemented by subclasses. + If the subclass places a page generator in + :attr:`self.generator<generator>`, Bot will process each page in the + generator, invoking the method :meth:`treat` which must then be + implemented by subclasses.
- Each item processed by treat() must be a :py:obj:`pywikibot.page.BasePage` - type. Use init_page() to upcast the type. To enable other types, set - BaseBot.treat_page_type to an appropriate type; your bot should - derive from BaseBot in that case and handle site properties. + Each item processed by :meth:`treat` must be a + :class:`pywikibot.page.BasePage` type. Use :meth:`init_page` to + upcast the type. To enable other types, set + :attr:`BaseBot.treat_page_type` to an appropriate type; your bot + should derive from :class:`BaseBot` in that case and handle site + properties.
If the subclass does not set a generator, or does not override - treat() or run(), NotImplementedError is raised. + :meth:`treat` or :meth:`run`, NotImplementedError is raised.
- For bot options handling refer OptionHandler class above. + For bot options handling refer :class:`OptionHandler` class above.
.. versionchanged:: 7.0 - A counter attribute is provided which is a collections.Counter; + A counter attribute is provided which is a `collections.Counter`; The default counters are 'read', 'write' and 'skip'. """
+ use_redirects = None # type: Optional[bool] + """Attribute to determine whether to use redirect pages. Set it to + True to use redirects only, set it to False to skip redirects. If + None both are processed. + + .. versionadded:: 7.2 + """ + # Handler configuration. # The values are the default values # Extend this in subclasses! @@ -1232,10 +1243,13 @@ 'always': False, # By default ask for confirmation when putting a page }
- # update_options can be used to update available_options; - # do not use it if the bot class is to be derived but use - # self.available_options.update(<dict>) initializer in such case update_options = {} # type: Dict[str, Any] + """update_options can be used to update available_options; + do not use it if the bot class is to be derived but use + self.available_options.update(<dict>) initializer in such case. + + .. versionadded:: 6.4 + """
_current_page = None # type: Optional[pywikibot.page.BasePage]
@@ -1243,13 +1257,14 @@ """Only accept 'generator' and options defined in available_options.
:param kwargs: bot options - :keyword generator: a generator processed by run method + :keyword generator: a :attr:`generator` processed by :meth:`run` method """ if 'generator' in kwargs: if hasattr(self, 'generator'): pywikibot.warn('{} has a generator already. Ignoring argument.' .format(self.__class__.__name__)) else: + #: generator processed by :meth:`run` method self.generator = kwargs.pop('generator')
self.available_options.update(self.update_options) @@ -1257,7 +1272,8 @@
self.counter = Counter() self._generator_completed = False - self.treat_page_type = pywikibot.page.BasePage # default type + #: instance variable to hold the default page type + self.treat_page_type = pywikibot.page.BasePage # type: Any
@property @deprecated("self.counter['read']", since='7.0.0') @@ -1510,14 +1526,27 @@
.. versionadded:: 3.0
+ .. versionchanged:: 7.2 + use :attr:`use_redirects` to handle redirects + :param page: Page object to be processed """ + if isinstance(self.use_redirects, bool) \ + and page.isRedirectPage() is not self.use_redirects: + pywikibot.warning( + 'Page {page} on {page.site} is skipped because it is {not_}' + 'a redirect' + .format(page=page, not_='not ' if self.use_redirects else '')) + return True + return False
- def treat(self, page: 'pywikibot.page.BasePage') -> None: + def treat(self, page: Any) -> None: """Process one page (abstract method).
- :param page: Page object to be processed + :param page: Object to be processed, usually a + :class:`pywikibot.page.BasePage`. For other page types the + :attr:`treat_page_type` must be set. """ raise NotImplementedError('Method {}.treat() not implemented.' .format(self.__class__.__name__)) @@ -1940,7 +1969,18 @@
class RedirectPageBot(CurrentPageBot):
- """A RedirectPageBot class which only treats redirects.""" + """A RedirectPageBot class which only treats redirects. + + .. deprecated:: 7.2 + use BaseBot attribute 'use_redirects = True' instead + """ + + def __init__(self, *args, **kwargs): + """Deprecate RedirectPageBot.""" + issue_deprecation_warning('RedirectPageBot', + "BaseBot attribute 'use_redirects = True'", + since='7.2.0') + super().__init__(*args, **kwargs)
def skip_page(self, page: 'pywikibot.page.BasePage') -> bool: """Treat only redirect pages and handle IsNotRedirectPageError.""" @@ -1954,7 +1994,18 @@
class NoRedirectPageBot(CurrentPageBot):
- """A NoRedirectPageBot class which only treats non-redirects.""" + """A NoRedirectPageBot class which only treats non-redirects. + + .. deprecated:: 7.2 + use BaseBot attribute 'use_redirects = False' instead + """ + + def __init__(self, *args, **kwargs): + """Deprecate NoRedirectPageBot.""" + issue_deprecation_warning('RedirectPageBot', + "BaseBot attribute 'use_redirects = False'", + since='7.2.0') + super().__init__(*args, **kwargs)
def skip_page(self, page: 'pywikibot.page.BasePage') -> bool: """Treat only non-redirect pages and handle IsRedirectPageError.""" diff --git a/pywikibot/specialbots/_unlink.py b/pywikibot/specialbots/_unlink.py index 76fd66f..70fe226 100644 --- a/pywikibot/specialbots/_unlink.py +++ b/pywikibot/specialbots/_unlink.py @@ -13,7 +13,6 @@ ChoiceException, ExistingPageBot, InteractiveReplace, - NoRedirectPageBot, ) from pywikibot.bot_choice import UnhandledAnswer from pywikibot.editor import TextEditor @@ -54,10 +53,12 @@ return answer
-class BaseUnlinkBot(ExistingPageBot, NoRedirectPageBot, AutomaticTWSummaryBot): +class BaseUnlinkBot(ExistingPageBot, AutomaticTWSummaryBot):
"""A basic bot unlinking a given link from the current page."""
+ use_redirects = False + def __init__(self, **kwargs) -> None: """Redirect all parameters and add namespace as an available option.""" self.available_options.update({ diff --git a/scripts/add_text.py b/scripts/add_text.py index 3cc2a96..b8b2e0e 100755 --- a/scripts/add_text.py +++ b/scripts/add_text.py @@ -68,11 +68,7 @@ import pywikibot from pywikibot import config, pagegenerators, textlib from pywikibot.backports import Dict, Sequence -from pywikibot.bot import ( - AutomaticTWSummaryBot, - ExistingPageBot, - NoRedirectPageBot, -) +from pywikibot.bot import AutomaticTWSummaryBot, ExistingPageBot
ARGS_TYPE = Dict[str, Union[bool, str]] @@ -101,10 +97,11 @@ docuReplacements = {'¶ms;': pagegenerators.parameterHelp} # noqa: N816
-class AddTextBot(AutomaticTWSummaryBot, ExistingPageBot, NoRedirectPageBot): +class AddTextBot(AutomaticTWSummaryBot, ExistingPageBot):
"""A bot which adds a text to a page."""
+ use_redirects = False summary_key = 'add_text-adding' update_options = DEFAULT_ARGS
diff --git a/scripts/basic.py b/scripts/basic.py index 9c07582..1bcd7ba 100755 --- a/scripts/basic.py +++ b/scripts/basic.py @@ -54,7 +54,6 @@ AutomaticTWSummaryBot, ConfigParserBot, ExistingPageBot, - NoRedirectPageBot, SingleSiteBot, )
@@ -71,7 +70,6 @@ # CurrentPageBot, # Sets 'current_page'. Process it in treat_page method. # # Not needed here because we have subclasses ExistingPageBot, # CurrentPageBot which only treats existing pages - NoRedirectPageBot, # CurrentPageBot which only treats non-redirects AutomaticTWSummaryBot, # Automatically defines summary; needs summary_key ):
@@ -86,6 +84,7 @@ :type summary_key: str """
+ use_redirects = False # treats non-redirects only summary_key = 'basic-changing'
update_options = { diff --git a/scripts/commonscat.py b/scripts/commonscat.py index aac502a..4f4bf22 100755 --- a/scripts/commonscat.py +++ b/scripts/commonscat.py @@ -46,7 +46,7 @@
import pywikibot from pywikibot import i18n, pagegenerators -from pywikibot.bot import ConfigParserBot, ExistingPageBot, NoRedirectPageBot +from pywikibot.bot import ConfigParserBot, ExistingPageBot from pywikibot.exceptions import InvalidTitleError from pywikibot.textlib import add_text
@@ -225,7 +225,7 @@ }
-class CommonscatBot(ConfigParserBot, ExistingPageBot, NoRedirectPageBot): +class CommonscatBot(ConfigParserBot, ExistingPageBot):
"""Commons categorisation bot.
@@ -233,6 +233,7 @@ CommonscatBot is a ConfigParserBot """
+ use_redirects = False update_options = {'summary': ''}
def skip_page(self, page): diff --git a/scripts/cosmetic_changes.py b/scripts/cosmetic_changes.py index 296ea02..f432a61 100755 --- a/scripts/cosmetic_changes.py +++ b/scripts/cosmetic_changes.py @@ -32,17 +32,13 @@ For further information see pywikibot/cosmetic_changes.py """ # -# (C) Pywikibot team, 2006-2021 +# (C) Pywikibot team, 2006-2022 # # Distributed under the terms of the MIT license. # import pywikibot from pywikibot import config, pagegenerators -from pywikibot.bot import ( - AutomaticTWSummaryBot, - ExistingPageBot, - NoRedirectPageBot, -) +from pywikibot.bot import AutomaticTWSummaryBot, ExistingPageBot from pywikibot.cosmetic_changes import CANCEL, CosmeticChangesToolkit from pywikibot.exceptions import InvalidPageError
@@ -59,12 +55,11 @@ }
-class CosmeticChangesBot(AutomaticTWSummaryBot, - ExistingPageBot, - NoRedirectPageBot): +class CosmeticChangesBot(AutomaticTWSummaryBot, ExistingPageBot):
"""Cosmetic changes bot."""
+ use_redirects = False summary_key = 'cosmetic_changes-standalone' update_options = { 'async': False, diff --git a/scripts/fixing_redirects.py b/scripts/fixing_redirects.py index 3814a1a..bdb3700 100755 --- a/scripts/fixing_redirects.py +++ b/scripts/fixing_redirects.py @@ -30,7 +30,6 @@ from pywikibot.bot import ( AutomaticTWSummaryBot, ExistingPageBot, - NoRedirectPageBot, SingleSiteBot, suggest_help, ) @@ -54,11 +53,11 @@ FEATURED_ARTICLES = 'Q4387444'
-class FixingRedirectBot(SingleSiteBot, ExistingPageBot, NoRedirectPageBot, - AutomaticTWSummaryBot): +class FixingRedirectBot(SingleSiteBot, ExistingPageBot, AutomaticTWSummaryBot):
"""Run over pages and resolve redirect links."""
+ use_redirects = False ignore_save_related_errors = True ignore_server_errors = True summary_key = 'fixing_redirects-fixing' diff --git a/scripts/newitem.py b/scripts/newitem.py index d828cad..693a79b 100755 --- a/scripts/newitem.py +++ b/scripts/newitem.py @@ -20,7 +20,7 @@
""" # -# (C) Pywikibot team, 2014-2021 +# (C) Pywikibot team, 2014-2022 # # Distributed under the terms of the MIT license. # @@ -30,7 +30,7 @@ import pywikibot from pywikibot import pagegenerators from pywikibot.backports import Set -from pywikibot.bot import NoRedirectPageBot, WikidataBot +from pywikibot.bot import WikidataBot from pywikibot.exceptions import ( LockedPageError, NoCreateError, @@ -42,10 +42,11 @@ DELETION_TEMPLATES = ('Q4847311', 'Q6687153', 'Q21528265')
-class NewItemRobot(WikidataBot, NoRedirectPageBot): +class NewItemRobot(WikidataBot):
"""A bot to create new items."""
+ use_redirect = False treat_missing_item = True update_options = { 'always': True, diff --git a/scripts/noreferences.py b/scripts/noreferences.py index 5805928..34ffb9e 100755 --- a/scripts/noreferences.py +++ b/scripts/noreferences.py @@ -38,7 +38,7 @@
import pywikibot from pywikibot import i18n, pagegenerators, textlib -from pywikibot.bot import ExistingPageBot, NoRedirectPageBot, SingleSiteBot +from pywikibot.bot import ExistingPageBot, SingleSiteBot from pywikibot.exceptions import LockedPageError from pywikibot.pagegenerators import XMLDumpPageGenerator
@@ -511,10 +511,12 @@ XMLDumpPageGenerator, text_predicate=_match_xml_page_text)
-class NoReferencesBot(SingleSiteBot, ExistingPageBot, NoRedirectPageBot): +class NoReferencesBot(SingleSiteBot, ExistingPageBot):
"""References section bot."""
+ use_redirects = False + def __init__(self, **kwargs) -> None: """Initializer.""" self.available_options.update({ diff --git a/scripts/parser_function_count.py b/scripts/parser_function_count.py index 5cdc4cd..83d4566 100755 --- a/scripts/parser_function_count.py +++ b/scripts/parser_function_count.py @@ -60,14 +60,15 @@
import pywikibot from pywikibot import pagegenerators -from pywikibot.bot import ExistingPageBot, NoRedirectPageBot, SingleSiteBot +from pywikibot.bot import ExistingPageBot, SingleSiteBot
-class ParserFunctionCountBot(SingleSiteBot, - ExistingPageBot, NoRedirectPageBot): +class ParserFunctionCountBot(SingleSiteBot, ExistingPageBot):
"""Bot class used for obtaining Parser function Count."""
+ use_redirects = False + update_options = { 'atleast': None, 'first': None, diff --git a/scripts/redirect.py b/scripts/redirect.py index 9be2554..277acf7 100755 --- a/scripts/redirect.py +++ b/scripts/redirect.py @@ -78,12 +78,7 @@ import pywikibot.data from pywikibot import i18n, pagegenerators, xmlreader from pywikibot.backports import Dict, List, Set, Tuple -from pywikibot.bot import ( - ExistingPageBot, - OptionHandler, - RedirectPageBot, - suggest_help, -) +from pywikibot.bot import ExistingPageBot, OptionHandler, suggest_help from pywikibot.exceptions import ( CircularRedirectError, InterwikiRedirectPageError, @@ -388,10 +383,12 @@ continue
-class RedirectRobot(ExistingPageBot, RedirectPageBot): +class RedirectRobot(ExistingPageBot):
"""Redirect bot."""
+ use_redirects = True + update_options = { 'limit': float('inf'), 'delete': False, diff --git a/scripts/reflinks.py b/scripts/reflinks.py index 06492d5..67283a7 100755 --- a/scripts/reflinks.py +++ b/scripts/reflinks.py @@ -63,12 +63,7 @@ import pywikibot from pywikibot import comms, config, i18n, pagegenerators, textlib from pywikibot.backports import Match, removeprefix -from pywikibot.bot import ( - ConfigParserBot, - ExistingPageBot, - NoRedirectPageBot, - SingleSiteBot, -) +from pywikibot.bot import ConfigParserBot, ExistingPageBot, SingleSiteBot from pywikibot.exceptions import ( FatalServerError, Server414Error, @@ -421,10 +416,7 @@ return text
-class ReferencesRobot(SingleSiteBot, - ConfigParserBot, - ExistingPageBot, - NoRedirectPageBot): +class ReferencesRobot(SingleSiteBot, ConfigParserBot, ExistingPageBot):
"""References bot.
@@ -432,6 +424,8 @@ ReferencesRobot is a ConfigParserBot """
+ use_redirects = False + update_options = { 'ignorepdf': False, 'limit': 0, # stop after n modified pages
pywikibot-commits@lists.wikimedia.org