Skip to content

Instantly share code, notes, and snippets.

@mara004
Last active May 3, 2025 21:37
Show Gist options
  • Save mara004/ec32b465789f67ea086720f8c66eb878 to your computer and use it in GitHub Desktop.
Save mara004/ec32b465789f67ea086720f8c66eb878 to your computer and use it in GitHub Desktop.
Wrap a python module's CLI entrypoint with argfiles support
#! /usr/bin/env python3
# SPDX-FileCopyrightText: 2025 mara004 <[email protected]>
# SPDX-License-Identifier: BSD-2-Clause
import sys
import shlex
from pathlib import Path
from importlib import import_module
from importlib.metadata import entry_points
def _read_argfiles(argv, parents=()):
for arg in argv:
if arg.startswith("@"):
argfile_path = Path(arg[1:]).expanduser().resolve()
if argfile_path in parents:
raise RuntimeError("self-includes are prohibited (would be infinite recursion)")
argfile_content = argfile_path.read_text().strip()
for l in argfile_content.split("\n"):
yield from _read_argfiles(shlex.split(l), parents=(*parents, argfile_path))
else:
yield arg
def main():
if sys.argv[1] in ("-h", "--help"):
print(f"Usage: {sys.argv[0]} MODNAME ARGFILE_ARGS", file=sys.stderr)
return
modname = sys.argv[1]
ep, = entry_points(group="console_scripts", name=modname)
modpath, funcname = ep.value.rsplit(":", maxsplit=1)
# list slicing copies
argv_iter = _read_argfiles(sys.argv[2:])
sys.argv.clear()
sys.argv.append(modname)
sys.argv.extend(argv_iter)
print(sys.argv)
module = import_module(modpath)
func = getattr(module, funcname)
func()
if __name__ == "__main__":
main()
@mara004
Copy link
Author

mara004 commented Apr 28, 2025

See also ctypesgen/ctypesgen#223 (comment) (thread) for background.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment