Skip to content

Instantly share code, notes, and snippets.

@MineRobber9000
Last active April 27, 2025 19:58
Show Gist options
  • Save MineRobber9000/485e648da3a77d5894fa1fe9189b5728 to your computer and use it in GitHub Desktop.
Save MineRobber9000/485e648da3a77d5894fa1fe9189b5728 to your computer and use it in GitHub Desktop.
A small script that prints function signatures based on ast.FunctionDef objects. Handles hint typing and defaults.

print_funcdefs.py

A small script that prints function signatures based on ast.FunctionDef objects. Handles hint typing and defaults.

Usage:

$ python print_funcdefs.py -h
usage: print_funcdefs.py [-h] [-v] file

Prints function signatures from a file (based on the AST representation).

positional arguments:
  file           The file to parse.

optional arguments:
  -h, --help     show this help message and exit
  -v, --verbose  Prints the dump of the FunctionDef object.
$ python print_funcdefs.py testpfd.py
square(x: int = 0) -> int
pow(x: int, p: int = 2) -> int
return_args(*args: int, **kwargs: Union[int, Tuple[int, ...]]) -> Dict[str, Union[int, Tuple[int, ...]]]
import ast, argparse
def get_value(node):
if type(node)==ast.Name:
return node.id
if type(node)==ast.Num:
return str(node.n)
if type(node)==ast.Subscript:
return get_value(node.value)+"["+get_value(node.slice)+"]"
if type(node)==ast.Index:
return get_value(node.value)
if type(node)==ast.Tuple:
return ", ".join(map(get_value,node.elts))
if type(node)==ast.Ellipsis:
return "..."
if type(node)==ast.NameConstant:
return str(node.value)
if type(node)==ast.Attribute:
return get_value(node.value)+"."+node.attr
print(ast.dump(node))
class PrintFuncDefs(ast.NodeVisitor):
VERBOSE = False
def visit_FunctionDef(self,node):
if self.VERBOSE: print("[VERBOSE]","FunctionDef object:",ast.dump(node))
out=node.name+"("
defs=len(node.args.args)-len(node.args.defaults)
for n, arg in enumerate(node.args.args):
out+=arg.arg
if arg.annotation: out+=": "+get_value(arg.annotation)
if n>=defs:
out+=" = "+get_value(node.args.defaults[n-defs])
out+=", "
if node.args.vararg:
out+="*"+node.args.vararg.arg
if node.args.vararg.annotation: out+=": "+get_value(node.args.vararg.annotation)
out+=", "
if node.args.kwarg:
out+="**"+node.args.kwarg.arg
if node.args.kwarg.annotation: out+=": "+get_value(node.args.kwarg.annotation)
out+=", "
if node.args.kwonlyargs:
if not node.args.vararg: out+="*, "
for n,arg in enumerate(node.args.kwonlyargs):
out+=arg.arg
if arg.annotation: out+=": "+get_value(arg.annotation)
if node.args.kw_defaults[n]: out+=" = "+get_value(node.args.kw_defaults[n])
out+=", "
out = (out[:-2] if (node.args.args or node.args.vararg or node.args.kwarg or node.args.kwonlyargs) else out)+")"
if node.returns: out+=" -> "+get_value(node.returns)
print(out)
if __name__=="__main__":
parser = argparse.ArgumentParser(description="Prints function signatures from a file (based on the AST representation).")
parser.add_argument("-v","--verbose",action="store_true",help="Prints the dump of the FunctionDef object.")
parser.add_argument("file",help="The file to parse.")
args = parser.parse_args()
with open(args.file) as f:
module = ast.parse(f.read())
PrintFuncDefs.VERBOSE=args.verbose
PrintFuncDefs().visit(module)
from typing import Dict, Union, Tuple
def square(x: int = 0) -> int:
return x**2
def pow(x: int,p: int = 2) -> int:
return x**p
def return_args(*args: int,**kwargs: Union[int, Tuple[int, ...]]) -> Dict[str, Union[int, Tuple[int, ...]]]:
kwargs["__args"] = args
return kwargs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment