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 Class commands.)


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 commands

When the 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)

    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.