old_contents: import inspect
  from functools import wraps
  
  from django.utils import six
  
  
  def kwarg_decorator(func):
      """
      Turns a function that accepts a single arg and some kwargs in to a
      decorator that can optionally be called with kwargs:
  
      .. code-block:: python
  
          @kwarg_decorator
          def my_decorator(func, bar=True, baz=None):
              ...
  
          @my_decorator
          def my_func():
              pass
  
          @my_decorator(bar=False)
          def my_other_func():
              pass
      """
      @wraps(func)
      def decorator(arg=None, **kwargs):
          if arg is None:
              return lambda arg: decorator(arg, **kwargs)
          return func(arg, **kwargs)
      return decorator
  
  
  def signature_matches(func, args=(), kwargs={}):
      """
      Work out if a function is callable with some args or not.
      """
      try:
          if six.PY3:
              sig = inspect.signature(func)
              sig.bind(*args, **kwargs)
          else:
              inspect.getcallarg(func, *args, **kwargs)
      except TypeError:
          return False
      else:
          return True
  
  
  def last_arg_decorator(func):
      """
      Allows a function to be used as either a decorator with args, or called as
      a normal function.
  
      @last_arg_decorator
      def register_a_thing(foo, func, bar=True):
          ..
  
      # Called as a decorator
      @register_a_thing("abc", bar=False)
      def my_func():
          ...
  
      # Called as a normal function call
      def my_other_func():
          ...
  
      register_a_thing("def", my_other_func, bar=True)
      """
      @wraps(func)
      def decorator(*args, **kwargs):
          if signature_matches(func, args, kwargs):
              return func(*args, **kwargs)
          else:
              return lambda last: func(*(args + (last,)), **kwargs)
      return decorator
  
new_contents: import inspect
  from functools import wraps
  
  
  def kwarg_decorator(func):
      """
      Turns a function that accepts a single arg and some kwargs in to a
      decorator that can optionally be called with kwargs:
  
      .. code-block:: python
  
          @kwarg_decorator
          def my_decorator(func, bar=True, baz=None):
              ...
  
          @my_decorator
          def my_func():
              pass
  
          @my_decorator(bar=False)
          def my_other_func():
              pass
      """
      @wraps(func)
      def decorator(arg=None, **kwargs):
          if arg is None:
              return lambda arg: decorator(arg, **kwargs)
          return func(arg, **kwargs)
      return decorator
  
  
  def signature_matches(func, args=(), kwargs={}):
      """
      Work out if a function is callable with some args or not.
      """
      try:
          sig = inspect.signature(func)
          sig.bind(*args, **kwargs)
      except TypeError:
          return False
      else:
          return True
  
  
  def last_arg_decorator(func):
      """
      Allows a function to be used as either a decorator with args, or called as
      a normal function.
  
      @last_arg_decorator
      def register_a_thing(foo, func, bar=True):
          ..
  
      # Called as a decorator
      @register_a_thing("abc", bar=False)
      def my_func():
          ...
  
      # Called as a normal function call
      def my_other_func():
          ...
  
      register_a_thing("def", my_other_func, bar=True)
      """
      @wraps(func)
      def decorator(*args, **kwargs):
          if signature_matches(func, args, kwargs):
              return func(*args, **kwargs)
          else:
              return lambda last: func(*(args + (last,)), **kwargs)
      return decorator
  
subject: Drop Python 2.0 support