On this page
Python source extractor module that uses AST parsing to extract functions, classes, dataclass fields, docstrings, and type annotations from .py files.
#selfdoc.extractors.python
#selfdoc.extractors.python
Python source extractor -- resolves directives by extracting from .py files.
Uses stdlib ast for parsing, no external dependencies. Handles:
- :::module -- extract module docstrings, functions, classes
- :::test -- extract test source code
- :::schema -- extract dataclass fields or JSON schema
- :::cli -- extract CLI help/usage info
- :::config -- extract config file contents as tables
#PythonExtractor
Python language extractor implementing LanguageExtractor protocol.
#name
def name(self) -> str#detect
def detect(self, dir_path: str) -> bool#resolve_path
def resolve_path(self, path_arg: str, source_paths: list[str], base_dir: str) -> str | None#extract
def extract(self, directive_name: str, attrs: dict[str, str], body: list[str], source_paths: list[str], base_dir: str) -> str#file_extensions
def file_extensions(self) -> list[str]#public_symbols
def public_symbols(self, file_path: str) -> list[str]Extract public top-level functions and classes from a Python file.
If the module defines __all__ as a literal list or tuple of strings, those names are returned directly (they ARE the public API, even if some start with _).
Otherwise falls back to heuristic: top-level functions and classes whose name does not start with underscore.
#_handle_module
def _handle_module(arg, body, source_paths, base_dir, attrs)Extract module docstring, functions, and classes.
Resolves dotted.path or file path to a .py file, parses with ast, and formats the result as markdown.
#_resolve_module_path
def _resolve_module_path(arg, source_paths, base_dir)Try to resolve a module argument to an actual .py file path.
Tries: dotted-to-path conversion within each source path, then direct path.
#_format_docstring
def _format_docstring(docstring)Transform Google-style docstring sections into markdown.
Detects section headers like Args:, Returns:, Raises: followed by indented name: description lines and converts them to bold headers with bullet lists so the markdown converter renders them as structured HTML instead of collapsing whitespace.
#_match_section_header
def _match_section_header(stripped)If stripped is a recognized section header like Args:, return the header name. Otherwise return None.
#_is_param_line
def _is_param_line(text)Check if a line looks like name: description or name (type): description.
#_split_param_line
def _split_param_line(text)Split name: description into (name, description).
Also handles name (type): description.
#_format_function
def _format_function(node, heading_level=2)Format a function/method node as markdown.
Skips private items (leading _) unless they have a docstring.
#_is_dataclass
def _is_dataclass(node)Check whether a class node has a @dataclass decorator.
#_format_dataclass_fields
def _format_dataclass_fields(node)Format dataclass fields as a Markdown field table.
Returns a table string or None if the class has no annotated fields.
#_format_class
def _format_class(node)Format a class node as markdown, including its public methods.
Dataclass classes without docstrings are rendered with a field table so their names appear in coverage and the generated docs are useful.
#_build_signature
def _build_signature(node)Build a human-readable function signature string from ast.arguments.
#_annotation_str
def _annotation_str(node)Convert an annotation AST node to a string, or empty string if None.
#_handle_test
def _handle_test(arg, body, source_paths, base_dir, attrs)Extract test source code from a test file.
arg format:
#_extract_node_source
def _extract_node_source(source_lines, node)Extract source lines for an AST node, stripping common indent.
#_handle_schema
def _handle_schema(arg, body, source_paths, base_dir, attrs)Extract schema information from JSON or Python dataclass.
arg format: - path/to/file.json -> render JSON keys as table - dotted.module ClassName -> extract dataclass fields
#_schema_from_dataclass
def _schema_from_dataclass(module_path, class_name, source_paths, base_dir)Extract dataclass/class fields with types and defaults from source.
#_extract_class_fields
def _extract_class_fields(class_node, source)Extract fields from a class (dataclass or regular class with annotations).
Produces a markdown table with Field, Type, Default, and Description columns.
#_get_inline_comment
def _get_inline_comment(source_lines, lineno)Extract an inline # comment from a source line (1-based lineno).
#_format_default
def _format_default(default_str)Format a default value for table display.
#_handle_cli
def _handle_cli(arg, body, source_paths, base_dir, attrs)Extract CLI help/usage information from a module.
For v1: extracts the module docstring and any string constants named HELP or USAGE, formatted as a code block.
#_handle_config
def _handle_config(arg, body, source_paths, base_dir, attrs)Extract config file contents as a documented table.
Supports JSON and TOML. Detects format from file extension.
#_handle_prose_desc
def _handle_prose_desc(arg, body, source_paths, base_dir, attrs)Extract only the module docstring as prose markdown.
Unlike :::module which also lists functions and classes, this directive returns just the module-level docstring formatted as prose text.