XZise has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/228348

Change subject: [FEAT] deprecated_args: Support callable replacements
......................................................................

[FEAT] deprecated_args: Support callable replacements

The replacement can now be a callable to allow dynamically to deprecate the
value or determine a different replacement argument name.

Change-Id: Ibc360bc0512fd1c66c774e8952e185bde49a80ba
---
M pywikibot/page.py
M pywikibot/tools/__init__.py
2 files changed, 59 insertions(+), 15 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/pywikibot/core 
refs/changes/48/228348/1

diff --git a/pywikibot/page.py b/pywikibot/page.py
index 479eace..1ad50ee 100644
--- a/pywikibot/page.py
+++ b/pywikibot/page.py
@@ -71,6 +71,20 @@
 logger = logging.getLogger("pywiki.wiki.page")
 
 
+# Outside a class as it needs to be called while the class is "build"
+def _bool_watch(old_name, args, kwargs):
+    """Convert boolean watch value into string value."""
+    if args is None and kwargs is None:
+        # Static call when constructing signature
+        return False
+    elif kwargs[old_name] is True:
+        return old_name, 'watch'
+    elif kwargs[old_name] is False:
+        return old_name, 'unwatch'
+    else:
+        return old_name
+
+
 # Note: Link objects (defined later on) represent a wiki-page's title, while
 # Page objects (defined here) represent the page itself, including its 
contents.
 
@@ -1026,7 +1040,7 @@
         # no restricting template found
         return True
 
-    @deprecated_args(comment='summary', sysop=None)
+    @deprecated_args(comment='summary', sysop=None, watch=_bool_watch)
     def save(self, summary=None, watch=None, minor=True, botflag=None,
              force=False, async=False, callback=None,
              apply_cosmetic_changes=None, **kwargs):
@@ -1067,10 +1081,6 @@
         """
         if not summary:
             summary = config.default_edit_summary
-        if watch is True:
-            watch = 'watch'
-        elif watch is False:
-            watch = 'unwatch'
         if not force and not self.botMayEdit():
             raise pywikibot.OtherPageSaveError(
                 self, "Editing restricted by {{bots}} template")
diff --git a/pywikibot/tools/__init__.py b/pywikibot/tools/__init__.py
index bd96771..e0e79c2 100644
--- a/pywikibot/tools/__init__.py
+++ b/pywikibot/tools/__init__.py
@@ -1170,9 +1170,16 @@
     """
     Decorator to declare multiple args deprecated.
 
-    @param arg_pairs: Each entry points to the new argument name. With True or
-        None it drops the value and prints a warning. If False it just drops
-        the value.
+    @param arg_pairs: Each entry points to the new argument name. If the new
+        arguments name is None the value is dropped with a warning. Otherwise
+        it needs to be a string or callable. The callable may return a sequence
+        or None or a string. If a sequence the first value will be the new
+        argument name and the second will be the new value instead of the
+        original value. The callable must accept three positional arguments:
+            the old name, the positional arguments, the keyword arguments
+        To fix the signature of the method it may be called with the latter two
+        arguments set to None. In that case it should only the new name (or
+        False if stays).
     """
     def decorator(obj):
         """Outer wrapper.
@@ -1201,8 +1208,33 @@
                     'new_arg': new_arg,
                 }
                 if old_arg in __kw:
-                    if new_arg not in [True, False, None]:
-                        if new_arg in __kw:
+                    if callable(new_arg):
+                        new_arg = new_arg(old_arg, __args, __kw)
+                    else:
+                        if new_arg is False or new_arg is True:
+                            new_arg = None
+
+                    if isinstance(new_arg, collections.Sequence):
+                        assert len(new_arg) == 2
+                        assert isinstance(new_arg[0], basestring)
+                        new_arg, new_value = new_arg
+                    elif new_arg is not None:
+                        assert isinstance(new_arg, basestring)
+                        new_value = __kw[old_arg]
+
+                    if new_arg is not None:
+                        if new_arg == old_arg:
+                            # if the value didn't change it wasn't deprecated
+                            # (e.g. when the parameter name stays)
+                            if __kw[new_arg] != new_value:
+                                warn('{old_val!r} value in {old_arg} argument '
+                                     'of {name} is deprecated; use {new_val!r} 
'
+                                     'instead.'.format(old_val=__kw[new_arg],
+                                                       new_val=new_value,
+                                                       **output_args),
+                                     DeprecationWarning, depth)
+                                __kw[new_arg] = new_value
+                        elif new_arg in __kw:
                             warn(u"%(new_arg)s argument of %(name)s "
                                  u"replaces %(old_arg)s; cannot use both."
                                  % output_args,
@@ -1214,12 +1246,9 @@
                                  u"is deprecated; use %(new_arg)s instead."
                                  % output_args,
                                  DeprecationWarning, depth)
-                            __kw[new_arg] = __kw[old_arg]
+                            __kw[new_arg] = new_value
                     else:
-                        if new_arg is False:
-                            cls = PendingDeprecationWarning
-                        else:
-                            cls = DeprecationWarning
+                        cls = DeprecationWarning
                         warn(u"%(old_arg)s argument of %(name)s is deprecated."
                              % output_args,
                              cls, depth)
@@ -1238,6 +1267,11 @@
             for param in wrapper.__signature__.parameters.values():
                 params[param.name] = param.replace()
             for old_arg, new_arg in arg_pairs.items():
+                if callable(new_arg):
+                    new_arg = new_arg(old_arg, None, None)
+                    if new_arg is False or new_arg == old_arg:
+                        # no namechange
+                        continue
                 params[old_arg] = inspect.Parameter(
                     old_arg, kind=inspect._POSITIONAL_OR_KEYWORD,
                     default='[deprecated name of ' + new_arg + ']'

-- 
To view, visit https://gerrit.wikimedia.org/r/228348
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ibc360bc0512fd1c66c774e8952e185bde49a80ba
Gerrit-PatchSet: 1
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: XZise <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to