#!/usr/bin/env python3

import argparse
import typing
from collections.abc import Callable, Sequence

class CallAction(argparse.Action):

	"""
	An :paramref:`~argparse.ArgumentParser.add_argument.action` which can be used when adding an argument to an :class:`argparse.ArgumentParser`.
	It immediately calls the function passed to :paramref:`callback` without checking if all command line arguments have been passed.
	If you omit the :paramref:`~argparse.ArgumentParser.add_argument.help` parameter the function must have a doc string which is used instead.

	For example:

	.. literalinclude:: ../../docs/source/examples/callaction/example.py
	   :language: python
	   :start-after: # ------- start -------
	   :end-before: # ------- end -------

	"""

	def __init__(self, option_strings: 'Sequence[str]', dest: str, callback: 'Callable[[], None]', help: 'str|None' = None, nargs: 'int|str' = 0) -> None:
		if help is None:
			if callback.__doc__ is None:
				raise TypeError("missing doc string for function %s" % callback.__name__)
			help = callback.__doc__.strip()
		argparse.Action.__init__(self, option_strings, dest, nargs=nargs, help=help)
		self.callback = callback

	def __call__(self, parser: argparse.ArgumentParser, namespace: argparse.Namespace, values: 'str|Sequence[typing.Any]|None', option_string: 'str|None' = None) -> None:
		if values is None:
			values = []
		elif isinstance(values, str):
			values = [values]
		self.callback(*values)
