<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def add(self, func: Callable, name: Optional[str]=None, queue: Optional[str]=None, max_retries: Optional[Number]=None, periodicity: Optional[timedelta]=None):
 """Register a task function. :arg func: a callable to be executed :arg name: name of the task, used later to schedule jobs :arg queue: queue of the task, the default is used if not provided :arg max_retries: maximum number of retries, the default is used if not provided :arg periodicity: for periodic tasks, delay between executions as a timedelta """

        if not name:
            raise ValueError('Each Spinach task needs a name')
        if name in self._tasks:
            raise ValueError('A task named {} already exists'.format(name))

        if queue is None:
            if self.queue:
                queue = self.queue
            else:
                queue = const.DEFAULT_QUEUE

        if max_retries is None:
            if self.max_retries:
                max_retries = self.max_retries
            else:
                max_retries = const.DEFAULT_MAX_RETRIES

        if periodicity is None:
            periodicity = self.periodicity

        if queue and queue.startswith('_'):
            raise ValueError('Queues starting with "_" are reserved by '
                             'Spinach for internal use')

        self._tasks[name] = Task(func, name, queue, max_retries, periodicity)