.. _subcommands: Subcommands =============== Instead of calling a horetu interface on a :py:class:``horetu.Program`` or callable, you can call it on any of the following. * list of callables * dictionary of strings to * callables or * lists of callables or * dictionaries of the same constraints * class, which acts like a combination of a callable and a dictionary (See :ref:`class-command`.) Example -------- The callables are turned into sub-commands. When dictionaries are passed, the keys of dictionaries become the names of the sub-commands Otherwise, the callables' names are used as sub-command names. :: import horetu f = g = h = i = j = lambda x: int(x) + 4 commands = { 'subcommand1': { 'subsubcommand1.1': f, 'subsubcommand1.2': g, }, 'subcommand2': h, 'subcommand3': { 'subsubcommand3.1': i, 'subsubcommand3.2': { 'subsubsubcommand3.2.1': j, } }, } application = horetu.irc(commands, cli=True) .. _class-command: Class commands -------------- When the :py:class:`horetu.Program` init method encounters a class, it treats it as a combination of a callable and a dictionary. The ``__new__`` method is used as the callable; attributes are used instead of dictionary items, where the attribute names corresponds to the dictionary keys, the attribute values correspond to the dictionary values, and the underscore-prefixed attributes are ignored. This way, you can make a program that has subcommands but still does something if no subcommand is set. I originally made this for web pages. :: class website(object): def __new__(a: int=7): return str(a) @staticmethod def section1(b: int=8): return str(b) application = horetu.wsgi_plain(website) Note that most interfaces are set up such that positional arguments to the ``__new__`` method clash with section names. 1. If the inputs match a subsection inside a class command, the subcommand is run. 2. Otherwise, if the class has a ``__new__`` method that takes any positional arguments, the ``__new__`` method is run. If it fails, the error is reported as an error at the class command's section, not at a subsection. 3. If the class does not have a ``__new__`` method or the ``__new__`` method does not take positional arguments, horetu reports that the subsection is not correct.