How to Parse Function Signatures in Python with inspect
Extract a function's parameter names, kinds, defaults, annotations, and return type using Python's built-in inspect module.
Python code
28 linesimport inspect
def example_function(a: int, b: str = "default", *args, c: float = 1.5, **kwargs) -> bool:
"""An example function with various parameter types."""
return True
def parse_signature(func):
"""Parse a function's signature using the inspect module."""
sig = inspect.signature(func)
parameters = {}
for name, param in sig.parameters.items():
parameters[name] = {
"kind": str(param.kind),
"default": param.default if param.default is not inspect.Parameter.empty else None,
"annotation": param.annotation if param.annotation is not inspect.Parameter.empty else None
}
return {
"name": func.__name__,
"parameters": parameters,
"return_annotation": sig.return_annotation if sig.return_annotation is not inspect.Signature.empty else None
}
if __name__ == "__main__":
result = parse_signature(example_function)
for key, value in result.items():
print(f"{key}: {value}")
Output
name: example_function
parameters: {'a': {'kind': 'POSITIONAL_OR_KEYWORD', 'default': None, 'annotation': <class 'int'>}, 'b': {'kind': 'POSITIONAL_OR_KEYWORD', 'default': 'default', 'annotation': <class 'str'>}, 'args': {'kind': 'VAR_POSITIONAL', 'default': None, 'annotation': None}, 'c': {'kind': 'KEYWORD_ONLY', 'default': 1.5, 'annotation': <class 'float'>}, 'kwargs': {'kind': 'VAR_KEYWORD', 'default': None, 'annotation': None}}
return_annotation: <class 'bool'>
How it works
The inspect.signature call introspects a callable and returns a Signature object holding parameter metadata. Each Parameter exposes its name, kind (e.g., positional, keyword-only, varargs), default value, and type annotation. The check against inspect.Parameter.empty distinguishes a missing default or annotation from a value of None, letting you store None for absent fields. This approach works for both plain functions and methods, making it a reliable foundation for building documentation generators, argument validators, or framework introspection tools.
Common mistakes
- Comparing defaults with `is None` instead of `is inspect.Parameter.empty`, which wrongly reports explicit `None` defaults as missing
- Forgetting that `*args` and `**kwargs` kinds are `VAR_POSITIONAL` and `VAR_KEYWORD`, not standard parameters
- Assuming annotations are strings — they remain actual type objects unless `from __future__ import annotations` is used
- Not handling callables that fail `inspect.signature`, like some builtins, without wrapping in try/except
Variations
- Use `inspect.getfullargspec(func)` for a simpler flat list of names and defaults when you don't need annotation or kind details
- Call `str(sig)` directly to get a compact one-line signature like `(a: int, b: str = 'default', *args, c: float = 1.5, **kwargs) -> bool`
Real-world use cases
- Building a CLI framework that auto-generates help text from function parameters and annotations.
- Creating an API dispatcher that maps HTTP request fields to function arguments based on signature metadata.
- Implementing a dependency injection container that inspects container functions to resolve required parameters automatically.
Sponsored
More from Functions & basics
- Add Type Hints to Function Parameters and Return in Python easy
- Benchmark list append vs comprehension in Python easy
- Build a Context Manager in Python with contextlib.contextmanager easy
- Build a Progress Callback Function for Loops in Python easy
- Cache expensive function with lru_cache in Python easy
- Calculate Time Difference Across Time Zones in Python easy
Keep learning
Related tutorials and quizzes for this topic.