'Initializer.
All parameters are optional.
Args:
payload: The payload data for this Task that will either be delivered
to the webhook as the HTTP request body or fetched by workers for pull
queues. This is only allowed for POST, PUT and PULL methods.
name: Name to give the Task; if not specified, a name will be
auto-generated when added to a queue and assigned to this object. Must
match the _TASK_NAME_PATTERN regular expression.
method: Method to use when accessing the webhook. Defaults to \'POST\'. If
set to \'PULL\', task will not be automatically delivered to the webhook,
instead it stays in the queue until leased.
url: Relative URL where the webhook that should handle this task is
located for this application. May have a query string unless this is
a POST method. Must not be specified if method is PULL.
headers: Dictionary of headers to pass to the webhook. Values in the
dictionary may be iterable to indicate repeated header fields. Must not
be specified if method is PULL.
params: Dictionary of parameters to use for Task. For POST and PULL
requests these params will be encoded as
\'application/x-www-form-urlencoded\' and set to the payload. For all
other methods, the parameters will be converted to a query string. Must
not be specified if the URL already contains a query string, or the
task already has payload.
countdown: Time in seconds into the future that this Task should execute.
Defaults to zero.
eta: A datetime.datetime specifying the absolute time at which the task
should be executed. Must not be specified if \'countdown\' is specified.
This may be timezone-aware or timezone-naive. If None, defaults to now.
For pull tasks, no worker will be able to lease this task before the
time indicated by eta.
retry_options: TaskRetryOptions used to control when the task will be
retried if it fails.
target: The alternate version/backend on which to execute this task, or
DEFAULT_APP_VERSION to execute on the application\'s default version.
tag: The tag to be used when grouping by tag (PULL tasks only).
Raises:
InvalidEtaError: if the ETA is too far into the future;
InvalidTagError: if the tag is too long;
InvalidTaskError: if any of the parameters are invalid;
InvalidTaskNameError: if the task name is invalid;
InvalidUrlError: if the task URL is invalid or too long;
TaskTooLargeError: if the task with its payload is too large.'

def __init__(self, payload=None, **kwargs):

    args_diff = (set(kwargs.iterkeys()) - self.__CONSTRUCTOR_KWARGS)
    if args_diff:
        raise TypeError(('Invalid    arguments:    %s' % ',    '.join(args_diff)))
    self.__name = kwargs.get('name')
    if (self.__name and (not _TASK_NAME_RE.match(self.__name))):
        raise InvalidTaskNameError(('Task    name    does    not    match    expression    "%s";    found    %s' % (_TASK_NAME_PATTERN, self.__name)))
    (self.__default_url, self.__relative_url, query) = Task.__determine_url(kwargs.get('url', ''))
    self.__headers = urlfetch._CaselessDict()
    self.__headers.update(kwargs.get('headers', {}))
    self.__method = kwargs.get('method', 'POST').upper()
    self.__tag = kwargs.get('tag')
    self.__payload = None
    self.__retry_count = 0
    self.__queue_name = None
    size_check = kwargs.get('_size_check', True)
    params = kwargs.get('params', {})
    for (header_name, environ_name) in _PRESERVE_ENVIRONMENT_HEADERS:
        value = os.environ.get(environ_name)
        if (value is not None):
            self.__headers.setdefault(header_name, value)
    self.__headers.setdefault('X-AppEngine-Current-Namespace', namespace_manager.get_namespace())
    if (query and params):
        raise InvalidTaskError('Query    string    and    parameters    both    present;    only    one    of    these    may    be    supplied')
    if ((self.__method != 'PULL') and (self.__tag is not None)):
        raise InvalidTaskError('tag    may    only    be    specified    for    PULL    tasks')
    if (self.__method == 'PULL'):
        if (not self.__default_url):
            raise InvalidTaskError('url    must    not    be    specified    for    PULL    tasks')
        if kwargs.get('headers'):
            raise InvalidTaskError('headers    must    not    be    specified    for    PULL    tasks')
        if kwargs.get('target'):
            raise InvalidTaskError('target    must    not    be    specified    for    PULL    tasks')
        if params:
            if payload:
                raise InvalidTaskError('Message    body    and    parameters    both    present    for    PULL    method;    only    one    of    these    may    be    supplied')
            payload = Task.__encode_params(params)
        if (payload is None):
            raise InvalidTaskError('payload    must    be    specified    for    PULL    task')
        self.__payload = Task.__convert_payload(payload, self.__headers)
    elif (self.__method == 'POST'):
        if (payload and params):
            raise InvalidTaskError('Message    body    and    parameters    both    present    for    POST    method;    only    one    of    these    may    be    supplied')
        elif query:
            raise InvalidTaskError('POST    method    may    not    have    a    query    string;    use    the    "params"    keyword    argument    instead')
        elif params:
            self.__payload = Task.__encode_params(params)
            self.__headers.setdefault('content-type', 'application/x-www-form-urlencoded')
        elif (payload is not None):
            self.__payload = Task.__convert_payload(payload, self.__headers)
    elif (self.__method in _NON_POST_HTTP_METHODS):
        if (payload and (self.__method not in _BODY_METHODS)):
            raise InvalidTaskError(('Payload    may    only    be    specified    for    methods    %s' % ',    '.join(_BODY_METHODS)))
        if payload:
            self.__payload = Task.__convert_payload(payload, self.__headers)
        if params:
            query = Task.__encode_params(params)
        if query:
            self.__relative_url = ('%s?%s' % (self.__relative_url, query))
    else:
        raise InvalidTaskError(('Invalid    method:    %s' % self.__method))
    self.__target = kwargs.get('target')
    self.__resolve_hostname_and_target()
    self.__headers_list = _flatten_params(self.__headers)
    self.__eta_posix = Task.__determine_eta_posix(kwargs.get('eta'), kwargs.get('countdown'))
    self.__eta = None
    self.__retry_options = kwargs.get('retry_options')
    self.__enqueued = False
    self.__deleted = False
    if ((self.__eta_posix - time.time()) > _MAX_COUNTDOWN_SECONDS):
        raise InvalidEtaError('ETA    too    far    in    the    future')
    if size_check:
        if (self.__method == 'PULL'):
            max_task_size_bytes = MAX_PULL_TASK_SIZE_BYTES
        else:
            max_task_size_bytes = MAX_PUSH_TASK_SIZE_BYTES
        if (self.size > max_task_size_bytes):
            raise TaskTooLargeError(('Task    size    must    be    less    than    %d;    found    %d' % (max_task_size_bytes, self.size)))
        if (self.__tag and (len(self.__tag) > MAX_TAG_LENGTH)):
            raise InvalidTagError(('Tag    must    be    <=    %d    bytes.    Got    a    %d    byte    tag.' % (MAX_TAG_LENGTH, len(self.__tag))))
