CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pydoclint

A Python docstring linter that checks arguments, returns, yields, and raises sections

Pending
Overview
Eval results
Files

utility-apis.mddocs/

Utility APIs

Comprehensive set of utility classes and functions for programmatic docstring analysis, AST processing, and argument handling.

Capabilities

Argument Handling Classes

Classes for representing and manipulating function arguments from both AST nodes and docstring parameters.

class Arg:
    """
    Represents a function argument with name and type hint information.
    
    Provides methods for comparing arguments and checking type hint presence,
    with factory methods for creating from different sources.
    """
    
    name: str
    typeHint: str
    
    def __init__(self, name: str, typeHint: str) -> None:
        """
        Initialize argument with name and type hint.
        
        Parameters:
        - name: Argument name
        - typeHint: Type hint string (empty string if no type hint)
        """
    
    def nameEquals(self, other: 'Arg') -> bool:
        """
        Check if argument names are equal.
        
        Parameters:
        - other: Another Arg object to compare with
        
        Returns:
        bool: True if names match
        """
    
    def hasTypeHint(self) -> bool:
        """
        Check if argument has a type hint.
        
        Returns:
        bool: True if type hint is present and non-empty
        """
    
    def isStarArg(self) -> bool:
        """
        Check if this is a star argument (*args or **kwargs).
        
        Returns:
        bool: True if argument name starts with * or **
        """
    
    def notStarArg(self) -> bool:
        """
        Check if this is not a star argument.
        
        Returns:
        bool: True if argument name doesn't start with * or **
        """
    
    @classmethod
    def fromDocstringParam(cls, param: DocstringParam) -> 'Arg':
        """
        Create Arg from docstring parameter.
        
        Parameters:
        - param: Docstring parameter object
        
        Returns:
        Arg: New argument object
        """
    
    @classmethod
    def fromDocstringAttr(cls, attr: DocstringAttr) -> 'Arg':
        """
        Create Arg from docstring attribute.
        
        Parameters:
        - attr: Docstring attribute object
        
        Returns:
        Arg: New argument object representing class attribute
        """
    
    @classmethod
    def fromAstArg(cls, astArg: ast.arg) -> 'Arg':
        """
        Create Arg from AST argument node.
        
        Parameters:
        - astArg: AST argument node
        
        Returns:
        Arg: New argument object
        """

class ArgList:
    """
    Container for multiple Arg objects with list-like operations.
    
    Provides methods for comparing argument lists, filtering, and
    various operations needed for docstring validation.
    """
    
    infoList: list[Arg]
    
    def __init__(self, infoList: list[Arg]) -> None:
        """
        Initialize argument list.
        
        Parameters:
        - infoList: List of Arg objects
        """
    
    @classmethod
    def fromDocstringParam(cls, params: list[DocstringParam]) -> 'ArgList':
        """
        Create ArgList from docstring parameters.
        
        Parameters:
        - params: List of docstring parameter objects
        
        Returns:
        ArgList: New argument list
        """
    
    @classmethod
    def fromDocstringAttr(cls, attrs: list[DocstringAttr]) -> 'ArgList':
        """
        Create ArgList from docstring attributes.
        
        Parameters:
        - attrs: List of docstring attribute objects
        
        Returns:
        ArgList: New argument list for class attributes
        """
    
    def noTypeHints(self) -> bool:
        """
        Check if no arguments have type hints.
        
        Returns:
        bool: True if no arguments have type hints
        """
    
    def notAllArgsHaveTypeHints(self) -> bool:
        """
        Check if not all arguments have type hints.
        
        Returns:
        bool: True if some arguments lack type hints
        """
    
    def exists(self) -> bool:
        """
        Check if argument list is not empty.
        
        Returns:
        bool: True if list contains arguments
        """
    
    def length(self) -> int:
        """
        Get number of arguments.
        
        Returns:
        int: Number of arguments in list
        """
    
    def equals(self, other: 'ArgList') -> bool:
        """
        Check if two argument lists have same names.
        
        Parameters:
        - other: Another ArgList to compare
        
        Returns:
        bool: True if argument names match
        """
    
    def subtract(self, other: 'ArgList') -> 'ArgList':
        """
        Subtract another argument list from this one.
        
        Parameters:
        - other: ArgList to subtract
        
        Returns:
        ArgList: New list with arguments not in other list
        """

Docstring Representation

Class for parsing and representing docstring content with style-aware parsing.

class Doc:
    """
    Represents a parsed docstring with style-aware section extraction.
    
    Parses docstrings in numpy, google, or sphinx style and provides
    access to different sections like arguments, returns, yields, etc.
    """
    
    def __init__(self, docstring: str, style: str = 'numpy') -> None:
        """
        Initialize docstring parser.
        
        Parameters:
        - docstring: Raw docstring text
        - style: Docstring style ('numpy', 'google', 'sphinx')
        """
    
    @property
    def isShortDocstring(self) -> bool:
        """
        Check if docstring contains only a short summary.
        
        Returns:
        bool: True if docstring has no parameter/return sections
        """
    
    @property
    def argList(self) -> ArgList:
        """
        Get argument list from docstring parameters section.
        
        Returns:
        ArgList: Arguments documented in docstring
        """
    
    @property
    def attrList(self) -> ArgList:
        """
        Get attribute list from docstring attributes section.
        
        Returns:
        ArgList: Class attributes documented in docstring
        """
    
    @property
    def hasReturnsSection(self) -> bool:
        """
        Check if docstring has a returns section.
        
        Returns:
        bool: True if returns section is present
        """
    
    @property
    def hasYieldsSection(self) -> bool:
        """
        Check if docstring has a yields section.
        
        Returns:
        bool: True if yields section is present
        """
    
    @property
    def hasRaisesSection(self) -> bool:
        """
        Check if docstring has a raises section.
        
        Returns:
        bool: True if raises section is present
        """
    
    @property
    def returns(self) -> list[DocstringParam]:
        """
        Get returns section parameters.
        
        Returns:
        list[DocstringParam]: Return value documentation
        """
    
    @property
    def yields(self) -> list[DocstringParam]:
        """
        Get yields section parameters.
        
        Returns:
        list[DocstringParam]: Yield value documentation
        """
    
    @property
    def raises(self) -> list[DocstringParam]:
        """
        Get raises section parameters.
        
        Returns:
        list[DocstringParam]: Exception documentation
        """

Return and Yield Representations

Data classes for representing return and yield information.

@dataclass
class ReturnArg:
    """
    Represents return value information from docstring or annotation.
    
    Contains type information and description for function return values.
    """
    
    type: str
    description: str
    
    def __post_init__(self) -> None:
        """Post-initialization processing."""

@dataclass  
class YieldArg:
    """
    Represents yield value information from docstring or annotation.
    
    Contains type information and description for generator yield values.
    """
    
    type: str
    description: str
    
    def __post_init__(self) -> None:
        """Post-initialization processing."""

AST Analysis Utilities

Functions for analyzing AST nodes to extract return, yield, and raise information.

def hasReturnAnnotation(node: FuncOrAsyncFuncDef) -> bool:
    """
    Check if function has return type annotation.
    
    Parameters:
    - node: Function or async function AST node
    
    Returns:
    bool: True if return annotation is present
    """

def isReturnAnnotationNone(node: FuncOrAsyncFuncDef) -> bool:
    """
    Check if return annotation is None.
    
    Parameters:
    - node: Function or async function AST node
    
    Returns:
    bool: True if return annotation is None
    """

def isReturnAnnotationNoReturn(node: FuncOrAsyncFuncDef) -> bool:
    """
    Check if return annotation is NoReturn.
    
    Parameters:
    - node: Function or async function AST node
    
    Returns:
    bool: True if return annotation is NoReturn
    """

def hasGeneratorAsReturnAnnotation(node: FuncOrAsyncFuncDef) -> bool:
    """
    Check if return annotation is a Generator type.
    
    Parameters:
    - node: Function or async function AST node
    
    Returns:
    bool: True if return annotation indicates generator
    """

def hasIteratorOrIterableAsReturnAnnotation(node: FuncOrAsyncFuncDef) -> bool:
    """
    Check if return annotation is Iterator or Iterable.
    
    Parameters:
    - node: Function or async function AST node
    
    Returns:
    bool: True if return annotation is Iterator/Iterable
    """

def hasYieldStatements(node: FuncOrAsyncFuncDef) -> bool:
    """
    Check if function contains yield statements.
    
    Parameters:
    - node: Function or async function AST node
    
    Returns:
    bool: True if function yields values
    """

def hasReturnStatements(node: FuncOrAsyncFuncDef) -> bool:
    """
    Check if function contains return statements.
    
    Parameters:
    - node: Function or async function AST node
    
    Returns:
    bool: True if function has return statements
    """

def hasBareReturnStatements(node: FuncOrAsyncFuncDef) -> bool:
    """
    Check if function contains bare return statements (return without value).
    
    Parameters:
    - node: Function or async function AST node
    
    Returns:
    bool: True if function has bare return statements
    """

def hasRaiseStatements(node: FuncOrAsyncFuncDef) -> bool:
    """
    Check if function contains raise statements.
    
    Parameters:
    - node: Function or async function AST node
    
    Returns:
    bool: True if function raises exceptions
    """

def hasAssertStatements(node: FuncOrAsyncFuncDef) -> bool:
    """
    Check if function contains assert statements.
    
    Parameters:
    - node: Function or async function AST node
    
    Returns:
    bool: True if function has assert statements
    """

def getRaisedExceptions(node: FuncOrAsyncFuncDef) -> list[str]:
    """
    Get list of exceptions raised by function.
    
    Parameters:
    - node: Function or async function AST node
    
    Returns:
    list[str]: Names of exceptions that may be raised
    """

Special Method Detection

Functions for detecting special method types and decorators.

def checkIsAbstractMethod(node: FuncOrAsyncFuncDef) -> bool:
    """
    Check if method is decorated with @abstractmethod.
    
    Parameters:
    - node: Function or async function AST node
    
    Returns:
    bool: True if method is abstract
    """

def checkIsPropertyMethod(node: FuncOrAsyncFuncDef) -> bool:
    """
    Check if method is decorated with @property.
    
    Parameters:
    - node: Function or async function AST node
    
    Returns:  
    bool: True if method is a property
    """

def checkMethodContainsSpecifiedDecorator(
    node: FuncOrAsyncFuncDef, 
    decorator_name: str
) -> bool:
    """
    Check if method has specific decorator.
    
    Parameters:
    - node: Function or async function AST node
    - decorator_name: Name of decorator to check for
    
    Returns:
    bool: True if decorator is present
    """

Docstring Parsing

Functions for parsing docstrings in different styles.

def parseDocstring(
    docstring: str, 
    style: str, 
    filename: str = '<unknown>', 
    lineNum: int = 0
) -> Doc | None:
    """
    Parse docstring with error handling.
    
    Parameters:
    - docstring: Raw docstring text
    - style: Docstring style ('numpy', 'google', 'sphinx')
    - filename: Source filename for error reporting
    - lineNum: Line number for error reporting
    
    Returns:
    Doc | None: Parsed docstring object, or None if parsing fails
    """

def parseDocstringInGivenStyle(docstring: str, style: str) -> Doc | None:
    """
    Parse docstring in specific style without error handling.
    
    Parameters:
    - docstring: Raw docstring text
    - style: Docstring style to use
    
    Returns:
    Doc | None: Parsed docstring object, or None if parsing fails
    """

Generic Utility Functions

Core utility functions for AST processing and string manipulation.

def collectFuncArgs(node: FuncOrAsyncFuncDef) -> list[ast.arg]:
    """
    Collect all function arguments from AST node.
    
    Parameters:
    - node: Function or async function AST node
    
    Returns:
    list[ast.arg]: All function arguments
    """

def getFunctionId(node: FuncOrAsyncFuncDef) -> tuple[int, int, str]:
    """
    Get function identifier information.
    
    Parameters:
    - node: Function or async function AST node
    
    Returns:
    tuple containing:
    - int: Line number
    - int: Column offset
    - str: Function name
    """

def detectMethodType(node: FuncOrAsyncFuncDef) -> MethodType:
    """
    Detect the type of method (function, method, classmethod, etc.).
    
    Parameters:
    - node: Function or async function AST node
    
    Returns:
    MethodType: Detected method type
    """

def getDocstring(node: ClassOrFunctionDef) -> str:
    """
    Extract docstring from class or function node.
    
    Parameters:
    - node: Class or function definition AST node
    
    Returns:
    str: Docstring text, or empty string if none
    """

def getNodeName(node: ast.AST) -> str:
    """
    Get name from AST node.
    
    Parameters:
    - node: AST node
    
    Returns:
    str: Node name if available, otherwise empty string
    """

def stripQuotes(string: str | None) -> str | None:
    """
    Remove surrounding quotes from string.
    
    Parameters:
    - string: String that may have quotes
    
    Returns:
    str | None: String without quotes, or None if input is None
    """

def specialEqual(str1: str, str2: str) -> bool:
    """
    Special equality check for type hints and arguments.
    
    Parameters:
    - str1: First string to compare
    - str2: Second string to compare
    
    Returns:
    bool: True if strings are considered equal
    """

def stripCommentsFromTypeHints(typeHint: str) -> str:
    """
    Remove comments from type hint strings.
    
    Parameters:
    - typeHint: Type hint string that may contain comments
    
    Returns:
    str: Type hint with comments removed
    """

Custom Exceptions

class EdgeCaseError(Exception):
    """
    Exception raised for edge cases in docstring analysis.
    
    Used to handle unusual or unexpected scenarios during
    AST analysis and docstring parsing.
    """
    pass

Usage Examples

Argument Analysis

import ast
from pydoclint.utils.arg import Arg, ArgList
from pydoclint.utils.generic import collectFuncArgs

# Parse function and analyze arguments
source = '''
def example_func(x: int, y: str = "default", *args, **kwargs) -> bool:
    """Example function."""
    return True
'''

tree = ast.parse(source)
func_node = tree.body[0]

# Get AST arguments
ast_args = collectFuncArgs(func_node)

# Create Arg objects
args = [Arg.fromAstArg(arg) for arg in ast_args]
arg_list = ArgList(args)

print(f"Function has {arg_list.length()} arguments")
print(f"All have type hints: {not arg_list.notAllArgsHaveTypeHints()}")

# Check individual arguments
for arg in args:
    print(f"Arg '{arg.name}': type hint = '{arg.typeHint}', is star = {arg.isStarArg()}")

Docstring Analysis

from pydoclint.utils.parse_docstring import parseDocstring
from pydoclint.utils.doc import Doc

docstring = '''
Example function.

Parameters
----------
x : int
    First parameter
y : str
    Second parameter

Returns
-------
bool
    Success flag
'''

# Parse docstring
doc = parseDocstring(docstring, "numpy")

if doc:
    print(f"Is short docstring: {doc.isShortDocstring}")
    print(f"Has returns section: {doc.hasReturnsSection}")
    print(f"Arguments: {[arg.name for arg in doc.argList.infoList]}")

    # Compare with function signature
    # ... validation logic here

AST Analysis

from pydoclint.utils.return_yield_raise import (
    hasReturnAnnotation, hasYieldStatements, hasRaiseStatements
)

# Analyze function characteristics
if hasReturnAnnotation(func_node):
    print("Function has return annotation")

if hasYieldStatements(func_node):
    print("Function is a generator")

if hasRaiseStatements(func_node):
    exceptions = getRaisedExceptions(func_node)
    print(f"Function may raise: {exceptions}")

Types

# Union types for AST nodes
FuncOrAsyncFuncDef = Union[ast.FunctionDef, ast.AsyncFunctionDef]
ClassOrFunctionDef = Union[ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef]

# Method type enumeration
class MethodType(Enum):
    FUNCTION = "function"
    METHOD = "method"
    CLASSMETHOD = "classmethod"
    STATICMETHOD = "staticmethod"
    PROPERTY = "property"

# Docstring parsing types from docstring_parser_fork
DocstringParam = Any  # Parameter from parsed docstring
DocstringAttr = Any   # Attribute from parsed docstring

Install with Tessl CLI

npx tessl i tessl/pypi-pydoclint

docs

baseline.md

cli.md

configuration.md

core-analysis.md

flake8-plugin.md

index.md

utility-apis.md

violations.md

tile.json