jenkins-bot has submitted this change. ( 
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/618928 )

Change subject: [IMPR] Improvements for OptionHandler
......................................................................

[IMPR] Improvements for OptionHandler

- get Bot options by Bot.opt.option attribute or Bot.opt[option] as well
- deprecate availableOptions  in favour of available_options due to
  naming convention
- deprecate setOptions in favour of set_options due to naming convention
- deprecate getOption in favour of the new implementation
- deprecate options attibute
- Update specialbots and basic.py as first step

Change-Id: I94e3fcb299e779aab7834b8feb042dfc4d6a0b9e
---
M pywikibot/bot.py
M pywikibot/specialbots/_unlink.py
M pywikibot/specialbots/_upload.py
M scripts/basic.py
4 files changed, 90 insertions(+), 56 deletions(-)

Approvals:
  Xqt: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/pywikibot/bot.py b/pywikibot/bot.py
index 619f6a6..4f59108 100644
--- a/pywikibot/bot.py
+++ b/pywikibot/bot.py
@@ -23,7 +23,7 @@
   scripts.ini configuration file. That file consists of sections, led by a
   C{[section]} header and followed by C{option: value} or C{option=value}
   entries. The section is the script name without .py suffix. All options
-  identified must be predefined in availableOptions dictionary.
+  identified must be predefined in available_options dictionary.

 * L{Bot}: The previous base class which should be avoided. This class is mainly
   used for bots which work with wikibase or together with an image repository.
@@ -126,6 +126,7 @@
     deprecated, deprecate_arg, deprecated_args, issue_deprecation_warning,
 )
 from pywikibot.tools._logging import LoggingFormatter, RotatingFileHandler
+from pywikibot.tools import classproperty
 from pywikibot.tools.formatter import color_format


@@ -980,6 +981,24 @@
     i18n.input('pywikibot-enter-finished-browser')


+class _OptionDict(dict):
+
+    """The option dict which holds the options of OptionHandler."""
+
+    def __init__(self, classname, options):
+        self.classname = classname
+        super().__init__(options)
+
+    def __missing__(self, key):
+        raise pywikibot.Error("'{}' is not a valid option for {}."
+                              .format(key, self.classname))
+    __getattr__ = dict.__getitem__
+
+
+_DEPRECATION_MSG = 'Optionhandler.opt.option attribute ' \
+                   'or Optionhandler.opt[option] item'
+
+
 class OptionHandler:

     """Class to get and set options."""
@@ -989,46 +1008,64 @@
     # The values are the default values
     # Overwrite this in subclasses!

-    availableOptions = {}  # type: Dict[str, Any]
+    available_options = {}  # type: Dict[str, Any]

     def __init__(self, **kwargs):
         """
-        Only accept options defined in availableOptions.
+        Only accept options defined in available_options.

         @param kwargs: bot options
         """
-        self.setOptions(**kwargs)
+        self.set_options(**kwargs)

+    @classproperty
+    @deprecated('available_options', since='20201006')
+    def availableOptions(cls):
+        """DEPRECATED. Available_options class property."""
+        return cls.available_options
+
+    @deprecated('set_options', since='20201006')
     def setOptions(self, **kwargs):
-        """
-        Set the instance options.
+        """DEPRECATED. Set the instance options."""
+        self.set_options(**kwargs)

-        @param kwargs: options
-        """
-        valid_options = set(self.availableOptions)
-        received_options = set(kwargs)
+    def set_options(self, **options):
+        """Set the instance options."""
+        valid_options = set(self.available_options)
+        received_options = set(options)

-        # contains the options overridden from defaults
-        self.options = {
-            opt: kwargs[opt] for opt in received_options & valid_options}
+        # self.opt contains all available options including defaults
+        self.opt = _OptionDict(self.__class__.__name__, self.available_options)
+        # self.options contains the options overridden from defaults
+        self._options = {opt: options[opt]
+                         for opt in received_options & valid_options}
+        self.opt.update(self.options)

         for opt in received_options - valid_options:
-            pywikibot.warning('%s is not a valid option. It was ignored.'
-                              % opt)
+            pywikibot.warning('{} is not a valid option. It was ignored.'
+                              .format(opt))

+    @deprecated(_DEPRECATION_MSG, since='20201006')
     def getOption(self, option):
-        """
-        Get the current value of an option.
+        """DEPRECATED. Get the current value of an option.

-        @param option: key defined in OptionHandler.availableOptions
+        @param option: key defined in OptionHandler.available_options
         @raise pywikibot.exceptions.Error: No valid option is given with
             option parameter
         """
-        try:
-            return self.options.get(option, self.availableOptions[option])
-        except KeyError:
-            raise pywikibot.Error("'{0}' is not a valid option for {1}."
-                                  .format(option, self.__class__.__name__))
+        return self.opt[option]
+
+    @property
+    @deprecated(_DEPRECATION_MSG, since='20201006', future_warning=True)
+    def options(self):
+        """DEPRECATED. Return changed options."""
+        return self._options
+
+    @options.setter
+    @deprecated(_DEPRECATION_MSG, since='20201006', future_warning=True)
+    def options(self, options):
+        """DEPRECATED. Return changed options."""
+        self.set_options(**options)


 class BaseBot(OptionHandler):
@@ -1051,7 +1088,7 @@
     # The values are the default values
     # Extend this in subclasses!

-    availableOptions = {
+    available_options = {
         'always': False,  # By default ask for confirmation when putting a page
     }

@@ -1059,7 +1096,7 @@

     def __init__(self, **kwargs):
         """
-        Only accept options defined in availableOptions.
+        Only accept options defined in available_options.

         @param kwargs: bot options
         """
@@ -1103,7 +1140,7 @@

     def user_confirm(self, question):
         """Obtain user response if bot option 'always' not enabled."""
-        if self.getOption('always'):
+        if self.opt.always:
             return True

         choice = pywikibot.input_choice(question,
@@ -1188,7 +1225,7 @@
         if not self.user_confirm('Do you want to accept these changes?'):
             return False

-        if 'asynchronous' not in kwargs and self.getOption('always'):
+        if 'asynchronous' not in kwargs and self.opt.always:
             kwargs['asynchronous'] = True

         ignore_save_related_errors = kwargs.pop('ignore_save_related_errors',
@@ -1574,7 +1611,7 @@

     """A bot class that can read options from scripts.ini file.

-    All options must be predefined in availableOptions dictionary. The type
+    All options must be predefined in available_options dictionary. The type
     of these options is responsible for the correct interpretation of the
     options type given by the .ini file. They can be interpreted as bool,
     int, float or str (default). The settings file may be like:
@@ -1588,22 +1625,22 @@

     The option values are interpreted in this order::

-    - availableOptions default setting
+    - available_options default setting
     - script.ini options settings
     - command line arguments
     """

     INI = 'scripts.ini'

-    def setOptions(self, **kwargs):
+    def set_options(self, **kwargs):
         """Read settings from scripts.ini file."""
         conf = configparser.ConfigParser(inline_comment_prefixes=[';'])
         section = calledModuleName()

         if (conf.read(self.INI) == [self.INI] and conf.has_section(section)):
             pywikibot.output('Reading settings from {} file.'.format(self.INI))
-            args = {}
-            for option, value in self.availableOptions.items():
+            options = {}
+            for option, value in self.available_options.items():
                 if not conf.has_option(section, option):
                     continue
                 # use a convenience parser method, default to get()
@@ -1613,15 +1650,15 @@
                     method = getattr(conf, 'getboolean')
                 else:
                     method = getattr(conf, 'get' + value_type, default)
-                args[option] = method(section, option)
-            for opt in set(conf.options(section)) - set(args):
+                options[option] = method(section, option)
+            for opt in set(conf.options(section)) - set(options):
                 pywikibot.warning(
                     '"{}" is not a valid option. It was ignored.'.format(opt))
-            args.update(kwargs)
+            options.update(kwargs)
         else:
-            args = kwargs
+            options = kwargs

-        super().setOptions(**args)
+        super().set_options(**options)


 class CurrentPageBot(BaseBot):
@@ -1798,7 +1835,7 @@

     @ivar create_missing_item: If True, new items will be created if the
         current page doesn't have one. Subclasses should override this in the
-        initializer with a bool value or using self.getOption.
+        initializer with a bool value or using self.opt attribute.

     @type create_missing_item: bool
     """
diff --git a/pywikibot/specialbots/_unlink.py b/pywikibot/specialbots/_unlink.py
index ce5afe9..abd2e1d 100644
--- a/pywikibot/specialbots/_unlink.py
+++ b/pywikibot/specialbots/_unlink.py
@@ -9,8 +9,6 @@
 #
 # Distributed under the terms of the MIT license.
 #
-from __future__ import absolute_import, division, unicode_literals
-
 from pywikibot.bot import (
     AlwaysChoice, AutomaticTWSummaryBot, ChoiceException, ExistingPageBot,
     InteractiveReplace, NoRedirectPageBot, UnhandledAnswer,
@@ -25,7 +23,7 @@

     def __init__(self):
         """Initializer."""
-        super(EditReplacement, self).__init__('edit', 'e')
+        super().__init__('edit', 'e')
         self.stop = True


@@ -35,10 +33,10 @@

     def __init__(self, bot):
         """Create default settings."""
-        super(InteractiveUnlink, self).__init__(
-            old_link=bot.pageToUnlink, new_link=False, default='u')
+        super().__init__(old_link=bot.pageToUnlink,
+                         new_link=False, default='u')
         self._always = AlwaysChoice(self, 'unlink all pages', 'a')
-        self._always.always = bot.getOption('always')
+        self._always.always = bot.opt.always
         self.additional_choices = [
             AlwaysChoice(self, 'unlink all on page', 'p'),
             self._always, EditReplacement()]
@@ -48,7 +46,7 @@

     def handle_answer(self, choice):
         """Handle choice and store in bot's options."""
-        answer = super(InteractiveUnlink, self).handle_answer(choice)
+        answer = super().handle_answer(choice)
         self._bot.options['always'] = self._always.always
         return answer

@@ -59,12 +57,12 @@

     def __init__(self, **kwargs):
         """Redirect all parameters and add namespace as an available option."""
-        self.availableOptions.update({
+        self.available_options.update({
             'namespaces': [],
             # Which namespaces should be processed?
             # default to [] which means all namespaces will be processed
         })
-        super(BaseUnlinkBot, self).__init__(**kwargs)
+        super().__init__(**kwargs)

     def _create_callback(self):
         """Create a new callback instance for replace_links."""
diff --git a/pywikibot/specialbots/_upload.py b/pywikibot/specialbots/_upload.py
index 7db395a..b842ff8 100644
--- a/pywikibot/specialbots/_upload.py
+++ b/pywikibot/specialbots/_upload.py
@@ -81,8 +81,8 @@
         @type always: bool
         """
         super().__init__(**kwargs)
-        always = self.getOption('always')
-        if (always and ignore_warning is not True and aborts is not True):
+        always = self.opt.always
+        if always and ignore_warning is not True and aborts is not True:
             raise ValueError('When always is set to True, either '
                              'ignore_warning or aborts must be set to True.')
         if always and not description:
@@ -218,7 +218,7 @@
             pywikibot.warning('file_url is not given. '
                               'Set to self.url by default.')

-        always = self.getOption('always')
+        always = self.opt.always
         # Isolate the pure name
         filename = file_url
         # Filename may be either a URL or a local file path
diff --git a/scripts/basic.py b/scripts/basic.py
index e5df728..8d14573 100755
--- a/scripts/basic.py
+++ b/scripts/basic.py
@@ -77,7 +77,7 @@
         """
         # Add your own options to the bot and set their defaults
         # -always option is predefined by BaseBot class
-        self.availableOptions.update({
+        self.available_options.update({
             'replace': False,  # delete old text and write the new text
             'summary': None,  # your own bot summary
             'text': 'Test',  # add this text from option. 'Test' is default
@@ -86,7 +86,6 @@

         # call initializer of the super class
         super().__init__(site=True, **kwargs)
-
         # assign the generator to the bot
         self.generator = generator

@@ -103,13 +102,13 @@

         # Retrieve your private option
         # Use your own text or use the default 'Test'
-        text_to_add = self.getOption('text')
+        text_to_add = self.opt.text

-        if self.getOption('replace'):
+        if self.opt.replace:
             # replace the page text
             text = text_to_add

-        elif self.getOption('top'):
+        elif self.opt.top:
             # put text on top
             text = text_to_add + text

@@ -119,7 +118,7 @@

         # if summary option is None, it takes the default i18n summary from
         # i18n subdirectory with summary_key as summary key.
-        self.put_current(text, summary=self.getOption('summary'))
+        self.put_current(text, summary=self.opt.summary)


 def main(*args) -> None:

--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/618928
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: I94e3fcb299e779aab7834b8feb042dfc4d6a0b9e
Gerrit-Change-Number: 618928
Gerrit-PatchSet: 8
Gerrit-Owner: Xqt <[email protected]>
Gerrit-Reviewer: D3r1ck01 <[email protected]>
Gerrit-Reviewer: Hazard-SJ <[email protected]>
Gerrit-Reviewer: Ladsgroup <[email protected]>
Gerrit-Reviewer: Mpaa <[email protected]>
Gerrit-Reviewer: Xqt <[email protected]>
Gerrit-Reviewer: Zhuyifei1999 <[email protected]>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged
_______________________________________________
Pywikibot-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/pywikibot-commits

Reply via email to