{"id":3890,"library":"autocommand","title":"autocommand","description":"autocommand is a Python library (current version 2.2.2) designed to simplify the creation of command-line programs from standard Python functions. It automatically converts a function's parameter signature into `argparse`-compatible command-line arguments and handles execution when the module is run as `__main__`. It has an active development status with a mature feature set.","status":"active","version":"2.2.2","language":"en","source_language":"en","source_url":"https://github.com/Lucretiel/autocommand","tags":["cli","command-line","argparse","decorator","automation"],"install":[{"cmd":"pip install autocommand","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Required Python version","package":"python","min_version":"3.7"}],"imports":[{"symbol":"autocommand","correct":"from autocommand import autocommand"}],"quickstart":{"code":"import os\nfrom autocommand import autocommand\n\n@autocommand(__name__)\ndef greet(name: str = 'World', excited: bool = False):\n    \"\"\"Greets the given name.\"\"\"\n    message = f\"Hello, {name}\"\n    if excited:\n        message += '!'\n    print(message)\n\n# To run from command line: python your_script.py John --excited\n# To run as a function (e.g., in a test):\n# if __name__ != '__main__':\n#     # In 2.x, calling greet() directly without __name__ returns a callable function\n#     # so this is how you'd explicitly call it if not running as __main__\n#     # For library usage, you might get the parser and call it like:\n#     # func = autocommand(False)(greet) # Pass False or omit argument to return wrapper\n#     # func(['Alice', '--excited'])\n","lang":"python","description":"Define a function and decorate it with `@autocommand(__name__)`. When the script is run directly, `autocommand` parses command-line arguments based on the function's signature and executes it. Arguments with default values or type annotations are automatically handled, including boolean flags."},"warnings":[{"fix":"If integrating or testing, retrieve the callable wrapper and invoke it with an argument list: `wrapper_func = autocommand(False)(your_function); wrapper_func(['arg1', '--flag'])`. Alternatively, ensure `autocommand` is passed `True` or `__name__` if direct execution is desired within a `__main__` block. The change was noted around 2.0.1 for README updates.","message":"In autocommand 2.x, the behavior of calling an `@autocommand`-decorated function directly (i.e., outside of `if __name__ == '__main__'` without passing `__name__` or `True` to the decorator) changed. Instead of immediately executing the function, it now returns a callable wrapper function, typically `main(argv=None)`. If you were relying on direct execution for testing or embedding, you must update your calls.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Be aware that `sys.exit` is called. For testing, consider catching `SystemExit` or refactoring logic to be testable without full command-line execution. For library use, call the decorated function explicitly with `autocommand(False)` to get the wrapper, which returns the result instead of calling `sys.exit`.","message":"When an `autocommand`-decorated function is run as the main program, `autocommand` internally uses `sys.exit()` with the function's return value. This can bypass normal Python program flow and exception handling mechanisms, which might be unexpected in certain embedding or testing scenarios.","severity":"gotcha","affected_versions":"All"},{"fix":"If you need to gracefully handle parsing errors or help requests without exiting the interpreter, wrap the call to the autocommand-generated function in a `try...except SystemExit:` block.","message":"Argument parsing errors (e.g., missing required arguments, invalid types) or the use of `-h`/`--help` will cause `SystemExit` to be raised by the underlying `argparse` mechanism. This is a standard behavior of `argparse` but can halt programs that don't explicitly handle it.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}