XZise has uploaded a new change for review.

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

Change subject: [FEAT] Deprecating multiple parameters at once
......................................................................

[FEAT] Deprecating multiple parameters at once

This allows to deprecate multitple parameters in one go. This helps
to shorten the stacktrace, because with @deprecate_arg it would add
one function call for each deprecated argument.

Also checks if the new parameter is already defined as a positional
parameter. Example:

  @deprecate_args(foo='bar')
  def method(bar, meh):
      # method logic here

  method(42, meh=47, foo=1337)

Previously it would set 'bar' to 1337 instead of 42, because it was
not explicitly set as a named parameter. This requires that all
@deprecate_args are placed before all method wrapping decorators to
get the original parameter order.

Change-Id: I30e1330065d7d19e900d40a661ad356c6b7427b9
---
M pywikibot/__init__.py
M pywikibot/tools.py
M scripts/category.py
3 files changed, 44 insertions(+), 25 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/pywikibot/core 
refs/changes/36/155536/1

diff --git a/pywikibot/__init__.py b/pywikibot/__init__.py
index 59bb683..e2dcb04 100644
--- a/pywikibot/__init__.py
+++ b/pywikibot/__init__.py
@@ -16,6 +16,7 @@
 import re
 import sys
 import threading
+import inspect
 
 if sys.version_info[0] == 2:
     from Queue import Queue
diff --git a/pywikibot/tools.py b/pywikibot/tools.py
index 462b5ef..272e101 100644
--- a/pywikibot/tools.py
+++ b/pywikibot/tools.py
@@ -286,32 +286,54 @@
 
 def deprecate_arg(old_arg, new_arg):
     """Decorator to declare old_arg deprecated and replace it with new_arg."""
+    return deprecate_args(**{old_arg: new_arg})
+
+
+def deprecate_args(**arg_pairs):
+    """
+    Decorator to declare mutliple args deprecated.
+
+    To use all features of this decorator, use this as the top most.
+
+    @param arg_pairs: Each entry points to the new argument name or None if
+        the value should be dropped."""
     _logger = ""
 
     def decorator(method):
         def wrapper(*__args, **__kw):
             meth_name = method.__name__
-            if old_arg in __kw:
-                if new_arg:
-                    if new_arg in __kw:
-                        warning(
+            argspec = inspect.getargspec(method)
+            original = method
+            while hasattr(original, '__original'):
+                original = original.__original
+            argspec = inspect.getargspec(original)
+            for old_arg, new_arg in arg_pairs.items():
+                if old_arg in __kw:
+                    if new_arg:
+                        # determine if new_arg is positionally given
+                        try:
+                            arg_pos = argspec[0].index(new_arg)
+                        except ValueError:
+                            arg_pos = len(argspec[0]) + 1  # is in args/kwargs
+                        if new_arg in __kw or len(__args) > arg_pos:
+                            warning(
 u"%(new_arg)s argument of %(meth_name)s replaces %(old_arg)s; cannot use both."
-                            % locals())
-                    else:
-                        warning(
+                                % locals())
+                        else:
+                            warning(
 u"%(old_arg)s argument of %(meth_name)s is deprecated; use %(new_arg)s 
instead."
-                            % locals())
-                        __kw[new_arg] = __kw[old_arg]
-                else:
-                    debug(
+                                % locals())
+                            __kw[new_arg] = __kw[old_arg]
+                    else:
+                        debug(
 u"%(old_arg)s argument of %(meth_name)s is deprecated."
-                        % locals(), _logger)
-                del __kw[old_arg]
+                            % locals(), _logger)
+                    del __kw[old_arg]
             return method(*__args, **__kw)
         wrapper.__doc__ = method.__doc__
         wrapper.__name__ = method.__name__
+        wrapper.__original = method
         return wrapper
-    return decorator
 
 
 if __name__ == "__main__":
diff --git a/scripts/category.py b/scripts/category.py
index 96d5e3e..d05804c 100755
--- a/scripts/category.py
+++ b/scripts/category.py
@@ -106,7 +106,7 @@
 import pywikibot
 from pywikibot import config, pagegenerators
 from pywikibot import i18n, textlib
-from pywikibot.tools import deprecate_arg, deprecated
+from pywikibot.tools import deprecate_args, deprecated
 
 # This is required for the text that is shown when you run this script
 # with the parameter -help.
@@ -242,7 +242,7 @@
 
     """A robot to mass-add a category to a list of pages."""
 
-    @deprecate_arg('editSummary', 'comment')
+    @deprecate_args(editSummary='comment')
     def __init__(self, generator, newcat=None, sort_by_last_name=False,
                  create=False, comment='', follow_redirects=False,
                  dry=False):
@@ -418,15 +418,11 @@
     DELETION_COMMENT_AUTOMATIC = 0
     DELETION_COMMENT_SAME_AS_EDIT_COMMENT = 1
 
-    @deprecate_arg("oldCatTitle", "oldcat")
-    @deprecate_arg("newCatTitle", "newcat")
-    @deprecate_arg("batchMode", "batch")
-    @deprecate_arg("editSummary", "comment")
-    @deprecate_arg("inPlace", "inplace")
-    @deprecate_arg("moveCatPage", "move_oldcat")
-    @deprecate_arg("deleteEmptySourceCat", "delete_oldcat")
-    @deprecate_arg("titleRegex", "title_regex")
-    @deprecate_arg("withHistory", "history")
+    @deprecate_args(oldCatTitle='oldcat', newCatTitle='newcat',
+                    batchMode='batch', editSummary='comment',
+                    inPlace='inplace', moveCatPage='move_oldcat',
+                    deleteEmptySourceCat='delete_oldcat',
+                    titleRegex='title_regex', withHistory='history')
     def __init__(self, oldcat, newcat=None, batch=False, comment='',
                  inplace=False, move_oldcat=True, delete_oldcat=True,
                  title_regex=None, history=False, pagesonly=False,

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I30e1330065d7d19e900d40a661ad356c6b7427b9
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