{"record":{"id":"2765b7cf5d59bd30","repo":"python/cpython","slug":"r-can-t-have-docstrings","errorCode":null,"errorMessage":"%r can't have docstrings","messagePattern":"%r can't have docstrings","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"Lib/ast.py","lineNumber":340,"sourceCode":"        if isinstance(field, AST):\n            yield field\n        elif isinstance(field, list):\n            for item in field:\n                if isinstance(item, AST):\n                    yield item\n\n\ndef get_docstring(node, clean=True):\n    \"\"\"\n    Return the docstring for the given node or None if no docstring can\n    be found.  If the node provided does not have docstrings a TypeError\n    will be raised.\n\n    If *clean* is `True`, all tabs are expanded to spaces and any whitespace\n    that can be uniformly removed from the second line onwards is removed.\n    \"\"\"\n    if not isinstance(node, (AsyncFunctionDef, FunctionDef, ClassDef, Module)):\n        raise TypeError(\"%r can't have docstrings\" % node.__class__.__name__)\n    if not(node.body and isinstance(node.body[0], Expr)):\n        return None\n    node = node.body[0].value\n    if isinstance(node, Constant) and isinstance(node.value, str):\n        text = node.value\n    else:\n        return None\n    if clean:\n        import inspect\n        text = inspect.cleandoc(text)\n    return text\n\n\n_line_pattern = None\ndef _splitlines_no_ff(source, maxlines=None):\n    \"\"\"Split a string into lines ignoring form feed and other chars.\n\n    This mimics how the Python parser splits source code.","sourceCodeStart":322,"sourceCodeEnd":358,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/ast.py#L322-L358","documentation":"get_docstring only accepts node types that can syntactically carry a docstring: Module, ClassDef, FunctionDef, AsyncFunctionDef. Passing any other AST node (Expression, Assign, If, etc.) raises TypeError with the node's class name. Note this is about the node kind, not about whether a docstring exists — an eligible node without a docstring returns None instead of raising.","triggerScenarios":"ast.get_docstring(tree.body[0]) where the first statement is an Assign (module-level constant) rather than an Expr/FunctionDef; calling it on an Expression wrapper instead of the Module; feeding nodes from a custom visitor that yields non-def nodes.","commonSituations":"Docstring extractors iterating module bodies assuming the first statement is always a def/class; processing notebooks or generated code where a pragma or __future__ import precedes functions; tools that walk all nodes and call get_docstring unconditionally.","solutions":["Pass the module node or an actual def/class node: ast.get_docstring(tree) or ast.get_docstring(node) after isinstance filtering.","Guard the call: if isinstance(node, (ast.Module, ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)).","When iterating statements, skip non-docstring-bearing nodes instead of blindly forwarding them."],"exampleFix":"# before\nfirst = tree.body[0]\ntext = ast.get_docstring(first)  # first is an Assign -> TypeError\n\n# after\nfor node in tree.body:\n    if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)):\n        text = ast.get_docstring(node)\n        break","handlingStrategy":"type-guard","validationCode":"DOCSTRING_NODES = (ast.Module, ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)\n\ndef docstring_of(node):\n    if isinstance(node, DOCSTRING_NODES):\n        return ast.get_docstring(node)\n    return None","typeGuard":"def can_have_docstring(node) -> bool:\n    return isinstance(node, (ast.Module, ast.ClassDef,\n                             ast.FunctionDef, ast.AsyncFunctionDef))","tryCatchPattern":"try:\n    text = ast.get_docstring(node)\nexcept TypeError as e:\n    if \"can't have docstrings\" in str(e):\n        text = None  # node kind cannot carry a docstring; treat as absent","preventionTips":["Filter nodes with isinstance before calling get_docstring in visitors.","Remember eligible nodes without docstrings return None — no exception needed.","Prefer calling get_docstring on the Module or def/class node directly."],"tags":["ast","docstring","typeerror","introspection"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}