docs: def Task(entry):  # pylint: disable=invalid-name
      """
      Decorator with which classes, who act as tasks in a `Lane`, must be decorated. When a class is
      being decorated, it becomes a child of `LaneTask`.
  
      Parameters
      ----------
      entry: The name of the task's "main" method, i.e. the method which is executed when task is run
  
      Returns
      -------
      wrapper (function): The actual decorator function
      """
      if not isinstance(entry, string_types):
          # In the event that no argument is supplied to the decorator, python passes the decorated
          # class itself as an argument. That way, we can detect if no argument (or an argument of
          # invalid type) was supplied. This allows passing of `entry` as both a named kwarg, and
          # as an arg. Isn't neat, but for now it suffices.
          raise TypeError('When decorating a class with `Task`, a single string argument must be '
                          'supplied, which specifies the "main" task method, i.e. the class\'s entry '
                          'point to the task.')
      else:
          def wrapper(cls):
              """The actual decorator function"""
              if isclass(cls):
                  if not hasattr(cls, entry):  # Check if cls has the specified entry method
                      raise TypeError('Method `%s` not found in class `%s`.' % (entry, cls.__name__))
  
                  # We will have to inspect the task class's `__init__` method later (by inspecting
                  # the arg signature, before it is instantiated). In various circumstances, classes
                  # will not have an unbound `__init__` method. Let's deal with that now already, by
                  # assigning an empty, unbound `__init__` method manually, in order to prevent
                  # errors later on during method inspection (not an issue in Python 3):
                  # - Whenever a class is not defined as a new-style class in Python 2.7, i.e. a
                  # sub-class of object, and it does not have a `__init__` method definition, the
                  # class will not have an attribute `__init__`
                  # - If a class misses a `__init__` method definition, but is defined as a
                  # new-style class, attribute `__init__` will be of type `slot wrapper`, which
                  # cannot be inspected (and it also doesn't seem possible to check if a method is of
                  # type `slot wrapper`, which is why we manually define one).
                  if not hasattr(cls, '__init__') or cls.__init__ == object.__init__:
                      init = MethodType(lambda self: None, None, cls) \
                          if PY2 else MethodType(lambda self: None, cls)
                      setattr(cls, '__init__', init)
  
                  # Check for attributes that will be overwritten, in order to warn the user
                  reserved_attributes = ('__getattr__', '__call__', '_entry_mtd', 'cache', 'uncache',
                                         'clear_cache', '_log_lock')
                  for attr in dir(cls):
                      if attr in reserved_attributes:
                          make_default_logger(INTERNAL_LOGGER_NAME).warning(
                              'Attribute `%s` of class `%s` will be overwritten when decorated with '
                              '`sparklanes.Task`! Avoid assigning any of the following attributes '
                              '`%s`', attr, cls.__name__, str(reserved_attributes)
                          )
  
                  assignments = {'_entry_mtd': entry,
                                 '__getattr__': lambda self, name: TaskCache.get(name),
                                 '__init__': cls.__init__,
                                 '_log_lock': Lock()}
                  for attr in WRAPPER_ASSIGNMENTS:
                      try:
                          assignments[attr] = getattr(cls, attr)
                      except AttributeError:
                          pass
  
                  # Build task as a subclass of LaneTask
                  return type('Task_%s' % cls.__name__, (LaneTask, cls, object), assignments)
              else:
                  raise TypeError('Only classes can be decorated with `Task`')
  
          return wrapper