jenkins-bot submitted this change.

View Change

Approvals: DannyS712: Looks good to me, but someone else must approve Xqt: Looks good to me, approved jenkins-bot: Verified
[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(-)

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 = {'&params;': 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

To view, visit change 775347. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: Ibbc97a3ade4c04e881afcd7a27e631197f0db730
Gerrit-Change-Number: 775347
Gerrit-PatchSet: 10
Gerrit-Owner: Xqt <info@gno.de>
Gerrit-Reviewer: D3r1ck01 <xsavitar.wiki@aol.com>
Gerrit-Reviewer: DannyS712 <dannys712.wiki@gmail.com>
Gerrit-Reviewer: Xqt <info@gno.de>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged