Add the tools sub-project with the run_llm batch runner
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
# Tools for A Feminist Audit of Pop Music.
|
||||
# Copyright 2026 imacat. All rights reserved.
|
||||
# Authors:
|
||||
# imacat@mail.imacat.idv.tw (imacat), 2026/7/31
|
||||
# AI assistance: Claude Code (Anthropic)
|
||||
"""The package-level command-line entry point.
|
||||
|
||||
Dispatches ``python -m pop_fem_audit_tools <subcommand>`` or the
|
||||
console script ``pop-fem-audit-tools <subcommand>`` to the main
|
||||
function of the corresponding tool module.
|
||||
"""
|
||||
import os.path
|
||||
import sys
|
||||
from collections.abc import Callable
|
||||
from importlib.machinery import ModuleSpec
|
||||
from types import ModuleType
|
||||
|
||||
from pop_fem_audit_tools import run_llm
|
||||
|
||||
MODULE_PROG: str = "python -m pop_fem_audit_tools"
|
||||
"""The program name when run with ``python -m``."""
|
||||
|
||||
SUBCOMMANDS: dict[str, Callable[[list[str] | None], int]] = {
|
||||
"run-llm": run_llm.main,
|
||||
}
|
||||
"""The dispatch table from the subcommand name to the tool main."""
|
||||
|
||||
|
||||
def prog() -> str:
|
||||
"""Return the program name shown in the usage messages.
|
||||
|
||||
:return: ``python -m pop_fem_audit_tools`` when run with
|
||||
``python -m``, or the basename of ``sys.argv[0]`` when run
|
||||
as a console script.
|
||||
"""
|
||||
if sys.argv[0].endswith("__main__.py"):
|
||||
return MODULE_PROG
|
||||
return os.path.basename(sys.argv[0])
|
||||
|
||||
|
||||
def usage() -> str:
|
||||
"""Return the usage text listing the available subcommands.
|
||||
|
||||
:return: The usage text.
|
||||
"""
|
||||
lines: list[str] = [
|
||||
f"usage: {prog()} <subcommand> [<argument>...]",
|
||||
"",
|
||||
"subcommands:"]
|
||||
lines.extend(f" {x}" for x in SUBCOMMANDS)
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
"""Dispatch a subcommand to its tool module.
|
||||
|
||||
:param argv: The command-line arguments, or None for ``sys.argv``.
|
||||
:return: The exit status: the status of the subcommand, 0 for the
|
||||
usage help, or non-zero on a usage error.
|
||||
"""
|
||||
args: list[str] = sys.argv[1:] if argv is None else argv
|
||||
if len(args) == 0:
|
||||
print("error: missing subcommand", file=sys.stderr)
|
||||
print(usage(), file=sys.stderr)
|
||||
return 2
|
||||
if args[0] in ("-h", "--help"):
|
||||
print(usage())
|
||||
return 0
|
||||
if args[0] not in SUBCOMMANDS:
|
||||
print(f"error: unknown subcommand \"{args[0]}\"",
|
||||
file=sys.stderr)
|
||||
print(usage(), file=sys.stderr)
|
||||
return 2
|
||||
prog_backup: str = sys.argv[0]
|
||||
main_module: ModuleType = sys.modules["__main__"]
|
||||
spec_backup: ModuleSpec | None = getattr(
|
||||
main_module, "__spec__", None)
|
||||
sys.argv[0] = f"{prog()} {args[0]}"
|
||||
main_module.__spec__ = None
|
||||
try:
|
||||
return SUBCOMMANDS[args[0]](args[1:])
|
||||
finally:
|
||||
sys.argv[0] = prog_backup
|
||||
main_module.__spec__ = spec_backup
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user