code: def upgrader(version=None):
      
  
      def decorator(func):
          # Save the version to update from
          func.__vers_upgrader__ = version
          return func
  
      # What is version?  It can be None, an int, or a callable,
      # depending on how @upgrader() was called
      if version is None:
          # Called as @upgrader(); return the decorator
          return decorator
      elif isinstance(version, six.integer_types):
          # Called as @upgrader(1); sanity-check version and return the
          # decorator
          if version < 1:
              raise TypeError("Invalid upgrader version number %r" % version)
          return decorator
      elif callable(version):
          # Called as @upgrader; use version = None and call the
          # decorator
          func = version
          version = None
          return decorator(func)
      else:
          # Called with an invalid version
          raise TypeError("Invalid upgrader version number %r" % version)
docs: A decorator for marking a method as an upgrader from an older
      version of a given object.  Can be used in two different ways:
  
      ``@upgrader``
          In this usage, the decorated method updates from the previous
          schema version to this schema version.
  
      ``@upgrader(number)``
          In this usage, the decorated method updates from the
          designated schema version to this schema version.
  
      Note that upgrader methods are implicitly class methods, as the
      ``Schema`` object has not been constructed at the time the
      upgrader method is called.  Also note that upgraders take a single
      argument--a dictionary of attributes--and must return a
      dictionary.  Upgraders may modify the argument in place, if
      desired.
  
      :param version: The version number the upgrader converts from.
  
      :returns: If called with no arguments or with an integer version,
                returns a decorator.  If called with a callable, returns
                the callable.