prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Replace deprecated inspect.getargspec call in log_call
  `inspect.getargspec` has been deprecated. Replace it with equivalent function call.
  
  </issue>
  <code>
  [start of src/tcms/xmlrpc/decorators.py]
  1 # -*- coding: utf-8 -*-
  2 
  3 import inspect
  4 import logging
  5 
  6 from functools import wraps
  7 
  8 from django.conf import settings
  9 from kobo.django.xmlrpc.models import XmlRpcLog
  10 
  11 
  12 __all__ = ('log_call',)
  13 
  14 logger = logging.getLogger('nitrate.xmlrpc')
  15 
  16 if settings.DEBUG:
  17     # To avoid pollute XMLRPC logs with those generated during development
  18     def create_log(user, method, args):
  19         log_msg = 'user: {}, method: {}, args: {}'.format(
  20             user.username if hasattr(user, 'username') else user,
  21             method,
  22             args)
  23         logger.debug(log_msg)
  24 else:
  25     create_log = XmlRpcLog.objects.create
  26 
  27 
  28 def log_call(*args, **kwargs):
  29     """Log XMLRPC-specific invocations
  30 
  31     This is copied from kobo.django.xmlrpc.decorators to add custom abitlities,
  32     so that we don't have to wait upstream to make the changes.
  33 
  34     Usage::
  35 
  36         from tcms.core.decorators import log_call
  37         @log_call(namespace='TestNamespace')
  38         def func(request):
  39             return None
  40     """
  41     namespace = kwargs.get('namespace', '')
  42     if namespace:
  43         namespace = namespace + '.'
  44 
  45     def decorator(function):
  46         argspec = inspect.getargspec(function)
  47         # Each XMLRPC method has an HttpRequest argument as the first one,
  48         # it'll be ignored in the log.
  49         arg_names = argspec.args[1:]
  50 
  51         @wraps(function)
  52         def _new_function(request, *args, **kwargs):
  53             try:
  54                 known_args = zip(arg_names, args)
  55                 unknown_args = list(enumerate(args[len(arg_names):]))
  56                 keyword_args = [(key, value) for key, value in
  57                                 kwargs.items()
  58                                 if (key, value) not in known_args]
  59 
  60                 create_log(user=request.user,
  61                            method=f'{namespace}{function.__name__}',
  62                            args=str(known_args + unknown_args + keyword_args))
  63             except Exception:
  64                 pass
  65             return function(request, *args, **kwargs)
  66 
  67         return _new_function
  68 
  69     return decorator
  70
  [end of src/tcms/xmlrpc/decorators.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/src/tcms/xmlrpc/decorators.py b/src/tcms/xmlrpc/decorators.py
  --- a/src/tcms/xmlrpc/decorators.py
  +++ b/src/tcms/xmlrpc/decorators.py
  @@ -28,7 +28,7 @@
   def log_call(*args, **kwargs):
       """Log XMLRPC-specific invocations
   
  -    This is copied from kobo.django.xmlrpc.decorators to add custom abitlities,
  +    This is copied from kobo.django.xmlrpc.decorators to add custom abilities,
       so that we don't have to wait upstream to make the changes.
   
       Usage::
  @@ -43,7 +43,7 @@
           namespace = namespace + '.'
   
       def decorator(function):
  -        argspec = inspect.getargspec(function)
  +        argspec = inspect.getfullargspec(function)
           # Each XMLRPC method has an HttpRequest argument as the first one,
           # it'll be ignored in the log.
           arg_names = argspec.args[1:]
  @@ -51,17 +51,19 @@
           @wraps(function)
           def _new_function(request, *args, **kwargs):
               try:
  -                known_args = zip(arg_names, args)
  +                known_args = list(zip(arg_names, args))
                   unknown_args = list(enumerate(args[len(arg_names):]))
  -                keyword_args = [(key, value) for key, value in
  -                                kwargs.items()
  -                                if (key, value) not in known_args]
  +                keyword_args = [
  +                    (key, value) for key, value in kwargs.items()
  +                    if (key, value) not in known_args
  +                ]
   
                   create_log(user=request.user,
                              method=f'{namespace}{function.__name__}',
                              args=str(known_args + unknown_args + keyword_args))
               except Exception:
  -                pass
  +                logger.exception(
  +                    f'Fail to log XMLRPC call on {function.__name__}')
               return function(request, *args, **kwargs)
   
           return _new_function
  
verification_info: {"golden_diff": "diff --git a/src/tcms/xmlrpc/decorators.py b/src/tcms/xmlrpc/decorators.py\n--- a/src/tcms/xmlrpc/decorators.py\n+++ b/src/tcms/xmlrpc/decorators.py\n@@ -28,7 +28,7 @@\n def log_call(*args, **kwargs):\n     \"\"\"Log XMLRPC-specific invocations\n \n-    This is copied from kobo.django.xmlrpc.decorators to add custom abitlities,\n+    This is copied from kobo.django.xmlrpc.decorators to add custom abilities,\n     so that we don't have to wait upstream to make the changes.\n \n     Usage::\n@@ -43,7 +43,7 @@\n         namespace = namespace + '.'\n \n     def decorator(function):\n-        argspec = inspect.getargspec(function)\n+        argspec = inspect.getfullargspec(function)\n         # Each XMLRPC method has an HttpRequest argument as the first one,\n         # it'll be ignored in the log.\n         arg_names = argspec.args[1:]\n@@ -51,17 +51,19 @@\n         @wraps(function)\n         def _new_function(request, *args, **kwargs):\n             try:\n-                known_args = zip(arg_names, args)\n+                known_args = list(zip(arg_names, args))\n                 unknown_args = list(enumerate(args[len(arg_names):]))\n-                keyword_args = [(key, value) for key, value in\n-                                kwargs.items()\n-                                if (key, value) not in known_args]\n+                keyword_args = [\n+                    (key, value) for key, value in kwargs.items()\n+                    if (key, value) not in known_args\n+                ]\n \n                 create_log(user=request.user,\n                            method=f'{namespace}{function.__name__}',\n                            args=str(known_args + unknown_args + keyword_args))\n             except Exception:\n-                pass\n+                logger.exception(\n+                    f'Fail to log XMLRPC call on {function.__name__}')\n             return function(request, *args, **kwargs)\n \n         return _new_function\n", "issue": "Replace deprecated inspect.getargspec call in log_call\n`inspect.getargspec` has been deprecated. Replace it with equivalent function call.\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\nimport inspect\nimport logging\n\nfrom functools import wraps\n\nfrom django.conf import settings\nfrom kobo.django.xmlrpc.models import XmlRpcLog\n\n\n__all__ = ('log_call',)\n\nlogger = logging.getLogger('nitrate.xmlrpc')\n\nif settings.DEBUG:\n    # To avoid pollute XMLRPC logs with those generated during development\n    def create_log(user, method, args):\n        log_msg = 'user: {}, method: {}, args: {}'.format(\n            user.username if hasattr(user, 'username') else user,\n            method,\n            args)\n        logger.debug(log_msg)\nelse:\n    create_log = XmlRpcLog.objects.create\n\n\ndef log_call(*args, **kwargs):\n    \"\"\"Log XMLRPC-specific invocations\n\n    This is copied from kobo.django.xmlrpc.decorators to add custom abitlities,\n    so that we don't have to wait upstream to make the changes.\n\n    Usage::\n\n        from tcms.core.decorators import log_call\n        @log_call(namespace='TestNamespace')\n        def func(request):\n            return None\n    \"\"\"\n    namespace = kwargs.get('namespace', '')\n    if namespace:\n        namespace = namespace + '.'\n\n    def decorator(function):\n        argspec = inspect.getargspec(function)\n        # Each XMLRPC method has an HttpRequest argument as the first one,\n        # it'll be ignored in the log.\n        arg_names = argspec.args[1:]\n\n        @wraps(function)\n        def _new_function(request, *args, **kwargs):\n            try:\n                known_args = zip(arg_names, args)\n                unknown_args = list(enumerate(args[len(arg_names):]))\n                keyword_args = [(key, value) for key, value in\n                                kwargs.items()\n                                if (key, value) not in known_args]\n\n                create_log(user=request.user,\n                           method=f'{namespace}{function.__name__}',\n                           args=str(known_args + unknown_args + keyword_args))\n            except Exception:\n                pass\n            return function(request, *args, **kwargs)\n\n        return _new_function\n\n    return decorator\n", "path": "src/tcms/xmlrpc/decorators.py"}]}