CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-griffe

Extract Python API signatures and detect breaking changes for documentation generation.

Pending
Overview
Eval results
Files

docstrings.mddocs/

Docstrings

Comprehensive docstring parsing system supporting multiple documentation formats. Griffe can parse and structure docstrings from Google, NumPy, and Sphinx styles, extracting parameters, return values, exceptions, examples, and other documentation elements into structured data.

Capabilities

Main Parsing Functions

Primary entry points for docstring parsing with format detection and specific parsers.

def parse(
    text: str,
    parser: Parser | str | None = None,
    **options: Any,
) -> list[DocstringSection]:
    """
    Parse a docstring using a specified parser.
    
    Main entry point for docstring parsing. Can use automatic detection
    or a specific parser format.
    
    Args:
        text: Raw docstring text to parse
        parser: Parser to use ("auto", "google", "numpy", "sphinx") or Parser enum
        **options: Parser-specific options passed to the parsing function
        
    Returns:
        list[DocstringSection]: Structured sections from the docstring
        
    Examples:
        Auto-detect format:
        >>> sections = griffe.parse(docstring_text)
        
        Use specific parser:
        >>> sections = griffe.parse(docstring_text, parser="google")
        
        With options:
        >>> sections = griffe.parse(docstring_text, parser="numpy", style="numpy")
    """

def parse_auto(text: str, **options: Any) -> list[DocstringSection]:
    """
    Parse a docstring by automatically detecting the style it uses.
    
    Analyzes the docstring content to determine whether it uses Google,
    NumPy, or Sphinx formatting conventions and parses accordingly.
    
    Args:
        text: Raw docstring text to parse
        **options: Options passed to the detected parser
        
    Returns:
        list[DocstringSection]: Structured sections from the docstring
        
    Examples:
        >>> sections = griffe.parse_auto('''
        ... Brief description.
        ... 
        ... Args:
        ...     param1: Description of param1.
        ...     param2: Description of param2.
        ... 
        ... Returns:
        ...     Description of return value.
        ... ''')
    """

Format-Specific Parsers

Dedicated parsers for each supported docstring format.

def parse_google(text: str, **options: Any) -> list[DocstringSection]:
    """
    Parse a Google-style docstring into structured sections and elements.
    
    Parses docstrings following Google's Python style guide conventions
    with sections like Args, Returns, Raises, Examples, etc.
    
    Args:
        text: Google-style docstring text
        **options: Google parser options including:
            - style: Parsing style variations
            - trim_doctest_flags: Remove doctest flags from examples
            
    Returns:
        list[DocstringSection]: Parsed sections
        
    Examples:
        >>> sections = griffe.parse_google('''
        ... Function description.
        ... 
        ... Args:
        ...     name (str): The person's name.
        ...     age (int, optional): The person's age. Defaults to 0.
        ... 
        ... Returns:
        ...     str: A greeting message.
        ... 
        ... Raises:
        ...     ValueError: If name is empty.
        ... ''')
    """

def parse_numpy(text: str, **options: Any) -> list[DocstringSection]:
    """
    Parse a NumPy/SciPy-style docstring into structured sections and elements.
    
    Parses docstrings following NumPy documentation conventions with
    sections separated by underlined headers.
    
    Args:
        text: NumPy-style docstring text
        **options: NumPy parser options
        
    Returns:
        list[DocstringSection]: Parsed sections
        
    Examples:
        >>> sections = griffe.parse_numpy('''
        ... Brief function description.
        ... 
        ... Parameters
        ... ----------
        ... name : str
        ...     The person's name.
        ... age : int, optional
        ...     The person's age (default is 0).
        ... 
        ... Returns
        ... -------
        ... str
        ...     A greeting message.
        ... ''')
    """

def parse_sphinx(text: str, **options: Any) -> list[DocstringSection]:
    """
    Parse a Sphinx-style docstring into structured sections and elements.
    
    Parses docstrings using Sphinx/reStructuredText field conventions
    with :param:, :returns:, :raises: directives.
    
    Args:
        text: Sphinx-style docstring text
        **options: Sphinx parser options
        
    Returns:
        list[DocstringSection]: Parsed sections
        
    Examples:
        >>> sections = griffe.parse_sphinx('''
        ... Brief function description.
        ... 
        ... :param name: The person's name.
        ... :type name: str
        ... :param age: The person's age.
        ... :type age: int
        ... :returns: A greeting message.
        ... :rtype: str
        ... :raises ValueError: If name is empty.
        ... ''')
    """

Style Detection

Functions for detecting and inferring docstring formats.

def infer_docstring_style(
    text: str,
    detection_method: DocstringDetectionMethod = DocstringDetectionMethod.HEURISTICS
) -> DocstringStyle | None:
    """
    Infer the docstring style from content using heuristics.
    
    Analyzes docstring text patterns to determine the most likely
    documentation format being used.
    
    Args:
        text: Docstring text to analyze
        detection_method: Method to use for detection
        
    Returns:
        DocstringStyle | None: Detected style or None if uncertain
        
    Examples:
        >>> style = griffe.infer_docstring_style('''
        ... Args:
        ...     param1: Description
        ... Returns:
        ...     Something
        ... ''')
        >>> print(style)  # DocstringStyle.GOOGLE
    """

# Available parsers mapping
parsers: dict[str, callable]
"""Dictionary mapping parser names to their parsing functions."""

Docstring Structure Classes

Base Classes

Foundation classes for docstring representation and parsing.

class DocstringSection:
    """
    Base class for docstring sections (Parameters, Returns, etc.).
    
    Represents a major section within a structured docstring such as
    parameter lists, return descriptions, or example code.
    """
    
    def __init__(self, kind: DocstringSectionKind, title: str | None = None) -> None:
        """
        Initialize docstring section.
        
        Args:
            kind: Type of section (parameters, returns, etc.)
            title: Optional custom title for the section
        """
    
    @property
    def kind(self) -> DocstringSectionKind:
        """The section type/kind."""
    
    @property
    def title(self) -> str | None:
        """Optional section title."""

class DocstringElement:
    """
    Base class for individual elements within docstring sections.
    
    Represents discrete pieces of information within sections, such as
    individual parameters, return values, or exceptions.
    """
    
    def __init__(self, description: str = "") -> None:
        """
        Initialize docstring element.
        
        Args:
            description: Element description text
        """
    
    @property
    def description(self) -> str:
        """Element description text."""

class DocstringNamedElement(DocstringElement):
    """
    Base class for named docstring elements (parameters, attributes, etc.).
    
    Extends DocstringElement with name and type annotation support
    for elements that have identifiers.
    """
    
    def __init__(
        self,
        name: str,
        description: str = "",
        annotation: str | None = None,
    ) -> None:
        """
        Initialize named element.
        
        Args:
            name: Element name/identifier
            description: Element description  
            annotation: Type annotation string
        """
    
    @property
    def name(self) -> str:
        """Element name."""
    
    @property
    def annotation(self) -> str | None:
        """Type annotation string."""

Specific Element Types

Concrete implementations for different kinds of docstring elements.

class DocstringParameter(DocstringNamedElement):
    """
    Class representing parameter documentation in docstrings.
    
    Used for function/method parameters with names, types, descriptions,
    and default value information.
    """
    
    def __init__(
        self,
        name: str,
        description: str = "",
        annotation: str | None = None,
        default: str | None = None,
    ) -> None:
        """
        Initialize parameter documentation.
        
        Args:
            name: Parameter name
            description: Parameter description
            annotation: Type annotation
            default: Default value string
        """
    
    @property
    def default(self) -> str | None:
        """Default value string."""

class DocstringReturn(DocstringElement):
    """
    Class representing return value documentation in docstrings.
    
    Documents function return values with type and description information.
    """
    
    def __init__(
        self,
        description: str = "",
        annotation: str | None = None,
    ) -> None:
        """
        Initialize return documentation.
        
        Args:
            description: Return value description
            annotation: Return type annotation
        """
    
    @property
    def annotation(self) -> str | None:
        """Return type annotation."""

class DocstringRaise(DocstringNamedElement):
    """
    Class representing exception/raise documentation in docstrings.
    
    Documents exceptions that functions may raise with type and description.
    """

class DocstringYield(DocstringElement):
    """
    Class representing yield documentation for generator functions.
    
    Documents values yielded by generator functions.
    """
    
    def __init__(
        self,
        description: str = "",
        annotation: str | None = None,
    ) -> None:
        """
        Initialize yield documentation.
        
        Args:
            description: Yield value description
            annotation: Yield type annotation
        """

class DocstringAttribute(DocstringNamedElement):
    """
    Class representing attribute documentation in docstrings.
    
    Used for documenting class attributes, instance variables, and
    module-level variables.
    """

class DocstringAdmonition(DocstringElement):
    """
    Class representing admonition elements in docstrings.
    
    Handles special notices like Note, Warning, See Also, etc.
    """
    
    def __init__(
        self,
        kind: str,
        description: str = "",
        title: str | None = None,
    ) -> None:
        """
        Initialize admonition.
        
        Args:
            kind: Admonition type (note, warning, etc.)
            description: Admonition content
            title: Optional custom title
        """
    
    @property
    def kind(self) -> str:
        """Admonition type."""
    
    @property
    def title(self) -> str | None:
        """Optional admonition title."""

Section Types

Concrete section implementations for different docstring areas.

class DocstringSectionParameters(DocstringSection):
    """Section containing function parameter documentation."""
    
    def __init__(self, parameters: list[DocstringParameter]) -> None:
        """Initialize parameters section."""
    
    @property
    def parameters(self) -> list[DocstringParameter]:
        """List of documented parameters."""

class DocstringSectionReturns(DocstringSection):
    """Section containing return value documentation."""
    
    def __init__(self, returns: list[DocstringReturn]) -> None:
        """Initialize returns section."""
    
    @property
    def returns(self) -> list[DocstringReturn]:
        """List of return value documentation."""

class DocstringSectionRaises(DocstringSection):
    """Section containing exception/raises documentation."""
    
    def __init__(self, raises: list[DocstringRaise]) -> None:
        """Initialize raises section."""
    
    @property
    def raises(self) -> list[DocstringRaise]:
        """List of exception documentation."""

class DocstringSectionExamples(DocstringSection):
    """Section containing usage examples and code samples."""
    
    def __init__(self, examples: list[tuple[str, str]]) -> None:
        """
        Initialize examples section.
        
        Args:
            examples: List of (kind, text) tuples for examples
        """
    
    @property
    def examples(self) -> list[tuple[str, str]]:
        """List of examples as (kind, text) tuples."""

class DocstringSectionText(DocstringSection):
    """Section containing plain text content."""
    
    def __init__(self, text: str) -> None:
        """Initialize text section."""
    
    @property
    def text(self) -> str:
        """Section text content."""

Enumerations

from enum import Enum

class DocstringStyle(Enum):
    """Enumeration of supported docstring styles."""
    AUTO = "auto"
    GOOGLE = "google"
    NUMPY = "numpy"
    SPHINX = "sphinx"

class DocstringDetectionMethod(Enum):
    """Enumeration of methods for automatically detecting docstring styles."""
    HEURISTICS = "heuristics"

class DocstringSectionKind(Enum):
    """Enumeration of docstring section kinds."""
    TEXT = "text"
    PARAMETERS = "parameters"
    OTHER_PARAMETERS = "other_parameters"
    RETURNS = "returns"
    YIELDS = "yields"
    RECEIVES = "receives"
    RAISES = "raises" 
    WARNS = "warns"
    EXAMPLES = "examples"
    ATTRIBUTES = "attributes"
    FUNCTIONS = "functions"
    CLASSES = "classes"
    MODULES = "modules"
    DEPRECATED = "deprecated"
    ADMONITION = "admonition"

class Parser(Enum):
    """Enumeration of available docstring parsers."""
    AUTO = "auto"
    GOOGLE = "google"
    NUMPY = "numpy"
    SPHINX = "sphinx"

Usage Examples

Basic Docstring Parsing

import griffe

# Parse with auto-detection
docstring_text = '''
Brief function description.

Args:
    name (str): The person's name.
    age (int, optional): The person's age. Defaults to 0.

Returns:
    str: A greeting message.

Raises:
    ValueError: If name is empty.

Example:
    >>> greet("Alice", 25)
    "Hello, Alice (age: 25)!"
'''

sections = griffe.parse_auto(docstring_text)
print(f"Found {len(sections)} sections:")
for section in sections:
    print(f"  - {section.kind.value}")

Working with Parsed Sections

import griffe
from griffe import DocstringSectionKind

# Parse a Google-style docstring
sections = griffe.parse_google(docstring_text)

# Find specific sections
for section in sections:
    if section.kind == DocstringSectionKind.PARAMETERS:
        print("Parameters:")
        for param in section.parameters:
            print(f"  {param.name}: {param.annotation} - {param.description}")
            if param.default:
                print(f"    Default: {param.default}")
    
    elif section.kind == DocstringSectionKind.RETURNS:
        print("Returns:")
        for ret in section.returns:
            print(f"  {ret.annotation}: {ret.description}")
    
    elif section.kind == DocstringSectionKind.RAISES:
        print("Raises:")
        for exc in section.raises:
            print(f"  {exc.name}: {exc.description}")
    
    elif section.kind == DocstringSectionKind.EXAMPLES:
        print("Examples:")
        for kind, text in section.examples:
            print(f"  {kind}:")
            print(f"    {text}")

Format Detection and Comparison

import griffe

# Test different docstring styles
google_style = '''
Brief description.

Args:
    param1: Description 1.
    param2: Description 2.

Returns:
    Something useful.
'''

numpy_style = '''
Brief description.

Parameters
----------
param1 : str
    Description 1.
param2 : int
    Description 2.

Returns
-------
bool
    Something useful.
'''

sphinx_style = '''
Brief description.

:param param1: Description 1.
:type param1: str  
:param param2: Description 2.
:type param2: int
:returns: Something useful.
:rtype: bool
'''

# Detect styles
styles = [
    ("Google", google_style),
    ("NumPy", numpy_style), 
    ("Sphinx", sphinx_style)
]

for name, docstring in styles:
    detected = griffe.infer_docstring_style(docstring)
    print(f"{name} style detected as: {detected}")
    
    # Parse with detected style
    if detected:
        sections = griffe.parse(docstring, parser=detected.value)
        print(f"  Parsed into {len(sections)} sections")

Integration with Griffe Objects

import griffe

# Load a module and parse its docstrings
module = griffe.load("requests")

# Find a function and parse its docstring  
if "get" in module.functions:
    get_func = module.functions["get"]
    if get_func.docstring:
        sections = get_func.docstring.parse(parser="auto")
        
        print(f"Function: {get_func.name}")
        print(f"Docstring sections: {[s.kind.value for s in sections]}")
        
        # Extract parameter documentation
        for section in sections:
            if section.kind == griffe.DocstringSectionKind.PARAMETERS:
                print("Documented parameters:")
                for param in section.parameters:
                    print(f"  {param.name}: {param.description}")

# Parse all function docstrings in module
for func_name, func in module.functions.items():
    if func.docstring:
        try:
            sections = func.docstring.parse()
            param_count = sum(
                len(s.parameters) for s in sections 
                if s.kind == griffe.DocstringSectionKind.PARAMETERS
            )
            print(f"{func_name}: {param_count} documented parameters")
        except Exception as e:
            print(f"{func_name}: Failed to parse docstring - {e}")

Custom Docstring Processing

import griffe
from griffe import DocstringSectionKind

class DocstringAnalyzer:
    """Analyze docstring completeness and quality."""
    
    def analyze_function(self, func: griffe.Function) -> dict:
        """Analyze a function's docstring."""
        result = {
            "has_docstring": func.docstring is not None,
            "has_description": False,
            "documented_params": 0,
            "undocumented_params": 0,
            "has_return_doc": False,
            "has_examples": False,
            "issues": []
        }
        
        if not func.docstring:
            result["issues"].append("Missing docstring")
            return result
        
        # Parse the docstring
        try:
            sections = func.docstring.parse()
        except Exception as e:
            result["issues"].append(f"Failed to parse docstring: {e}")
            return result
        
        # Check for description
        text_sections = [s for s in sections if s.kind == DocstringSectionKind.TEXT]
        if text_sections and text_sections[0].text.strip():
            result["has_description"] = True
        
        # Check parameter documentation
        param_sections = [s for s in sections if s.kind == DocstringSectionKind.PARAMETERS]
        documented_param_names = set()
        if param_sections:
            for section in param_sections:
                for param in section.parameters:
                    documented_param_names.add(param.name)
        
        # Compare with actual parameters
        actual_param_names = {p.name for p in func.parameters if p.name not in ("self", "cls")}
        result["documented_params"] = len(documented_param_names)
        result["undocumented_params"] = len(actual_param_names - documented_param_names)
        
        # Check for undocumented parameters
        undocumented = actual_param_names - documented_param_names
        if undocumented:
            result["issues"].append(f"Undocumented parameters: {', '.join(undocumented)}")
        
        # Check return documentation
        return_sections = [s for s in sections if s.kind == DocstringSectionKind.RETURNS]
        result["has_return_doc"] = bool(return_sections)
        
        # Check for examples
        example_sections = [s for s in sections if s.kind == DocstringSectionKind.EXAMPLES]
        result["has_examples"] = bool(example_sections)
        
        return result

# Use the analyzer
analyzer = DocstringAnalyzer()
module = griffe.load("mypackage")

for func_name, func in module.functions.items():
    analysis = analyzer.analyze_function(func)
    print(f"\n{func_name}:")
    print(f"  Description: {'✓' if analysis['has_description'] else '✗'}")
    print(f"  Parameters: {analysis['documented_params']}/{analysis['documented_params'] + analysis['undocumented_params']}")
    print(f"  Return doc: {'✓' if analysis['has_return_doc'] else '✗'}")
    print(f"  Examples: {'✓' if analysis['has_examples'] else '✗'}")
    
    if analysis["issues"]:
        print(f"  Issues: {'; '.join(analysis['issues'])}")

Types

from enum import Enum
from typing import Any

# Docstring parsing types
class DocstringStyle(Enum): ...
class DocstringDetectionMethod(Enum): ...  
class DocstringSectionKind(Enum): ...
class Parser(Enum): ...

# Section and element base classes
class DocstringSection: ...
class DocstringElement: ...
class DocstringNamedElement(DocstringElement): ...

# Parser functions mapping
parsers: dict[str, callable]

Install with Tessl CLI

npx tessl i tessl/pypi-griffe

docs

agents.md

breaking-changes.md

cli.md

docstrings.md

extensions.md

index.md

loaders.md

models.md

serialization.md

tile.json