0
# Docstrings
1
2
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.
3
4
## Capabilities
5
6
### Main Parsing Functions
7
8
Primary entry points for docstring parsing with format detection and specific parsers.
9
10
```python { .api }
11
def parse(
12
text: str,
13
parser: Parser | str | None = None,
14
**options: Any,
15
) -> list[DocstringSection]:
16
"""
17
Parse a docstring using a specified parser.
18
19
Main entry point for docstring parsing. Can use automatic detection
20
or a specific parser format.
21
22
Args:
23
text: Raw docstring text to parse
24
parser: Parser to use ("auto", "google", "numpy", "sphinx") or Parser enum
25
**options: Parser-specific options passed to the parsing function
26
27
Returns:
28
list[DocstringSection]: Structured sections from the docstring
29
30
Examples:
31
Auto-detect format:
32
>>> sections = griffe.parse(docstring_text)
33
34
Use specific parser:
35
>>> sections = griffe.parse(docstring_text, parser="google")
36
37
With options:
38
>>> sections = griffe.parse(docstring_text, parser="numpy", style="numpy")
39
"""
40
41
def parse_auto(text: str, **options: Any) -> list[DocstringSection]:
42
"""
43
Parse a docstring by automatically detecting the style it uses.
44
45
Analyzes the docstring content to determine whether it uses Google,
46
NumPy, or Sphinx formatting conventions and parses accordingly.
47
48
Args:
49
text: Raw docstring text to parse
50
**options: Options passed to the detected parser
51
52
Returns:
53
list[DocstringSection]: Structured sections from the docstring
54
55
Examples:
56
>>> sections = griffe.parse_auto('''
57
... Brief description.
58
...
59
... Args:
60
... param1: Description of param1.
61
... param2: Description of param2.
62
...
63
... Returns:
64
... Description of return value.
65
... ''')
66
"""
67
```
68
69
### Format-Specific Parsers
70
71
Dedicated parsers for each supported docstring format.
72
73
```python { .api }
74
def parse_google(text: str, **options: Any) -> list[DocstringSection]:
75
"""
76
Parse a Google-style docstring into structured sections and elements.
77
78
Parses docstrings following Google's Python style guide conventions
79
with sections like Args, Returns, Raises, Examples, etc.
80
81
Args:
82
text: Google-style docstring text
83
**options: Google parser options including:
84
- style: Parsing style variations
85
- trim_doctest_flags: Remove doctest flags from examples
86
87
Returns:
88
list[DocstringSection]: Parsed sections
89
90
Examples:
91
>>> sections = griffe.parse_google('''
92
... Function description.
93
...
94
... Args:
95
... name (str): The person's name.
96
... age (int, optional): The person's age. Defaults to 0.
97
...
98
... Returns:
99
... str: A greeting message.
100
...
101
... Raises:
102
... ValueError: If name is empty.
103
... ''')
104
"""
105
106
def parse_numpy(text: str, **options: Any) -> list[DocstringSection]:
107
"""
108
Parse a NumPy/SciPy-style docstring into structured sections and elements.
109
110
Parses docstrings following NumPy documentation conventions with
111
sections separated by underlined headers.
112
113
Args:
114
text: NumPy-style docstring text
115
**options: NumPy parser options
116
117
Returns:
118
list[DocstringSection]: Parsed sections
119
120
Examples:
121
>>> sections = griffe.parse_numpy('''
122
... Brief function description.
123
...
124
... Parameters
125
... ----------
126
... name : str
127
... The person's name.
128
... age : int, optional
129
... The person's age (default is 0).
130
...
131
... Returns
132
... -------
133
... str
134
... A greeting message.
135
... ''')
136
"""
137
138
def parse_sphinx(text: str, **options: Any) -> list[DocstringSection]:
139
"""
140
Parse a Sphinx-style docstring into structured sections and elements.
141
142
Parses docstrings using Sphinx/reStructuredText field conventions
143
with :param:, :returns:, :raises: directives.
144
145
Args:
146
text: Sphinx-style docstring text
147
**options: Sphinx parser options
148
149
Returns:
150
list[DocstringSection]: Parsed sections
151
152
Examples:
153
>>> sections = griffe.parse_sphinx('''
154
... Brief function description.
155
...
156
... :param name: The person's name.
157
... :type name: str
158
... :param age: The person's age.
159
... :type age: int
160
... :returns: A greeting message.
161
... :rtype: str
162
... :raises ValueError: If name is empty.
163
... ''')
164
"""
165
```
166
167
### Style Detection
168
169
Functions for detecting and inferring docstring formats.
170
171
```python { .api }
172
def infer_docstring_style(
173
text: str,
174
detection_method: DocstringDetectionMethod = DocstringDetectionMethod.HEURISTICS
175
) -> DocstringStyle | None:
176
"""
177
Infer the docstring style from content using heuristics.
178
179
Analyzes docstring text patterns to determine the most likely
180
documentation format being used.
181
182
Args:
183
text: Docstring text to analyze
184
detection_method: Method to use for detection
185
186
Returns:
187
DocstringStyle | None: Detected style or None if uncertain
188
189
Examples:
190
>>> style = griffe.infer_docstring_style('''
191
... Args:
192
... param1: Description
193
... Returns:
194
... Something
195
... ''')
196
>>> print(style) # DocstringStyle.GOOGLE
197
"""
198
199
# Available parsers mapping
200
parsers: dict[str, callable]
201
"""Dictionary mapping parser names to their parsing functions."""
202
```
203
204
## Docstring Structure Classes
205
206
### Base Classes
207
208
Foundation classes for docstring representation and parsing.
209
210
```python { .api }
211
class DocstringSection:
212
"""
213
Base class for docstring sections (Parameters, Returns, etc.).
214
215
Represents a major section within a structured docstring such as
216
parameter lists, return descriptions, or example code.
217
"""
218
219
def __init__(self, kind: DocstringSectionKind, title: str | None = None) -> None:
220
"""
221
Initialize docstring section.
222
223
Args:
224
kind: Type of section (parameters, returns, etc.)
225
title: Optional custom title for the section
226
"""
227
228
@property
229
def kind(self) -> DocstringSectionKind:
230
"""The section type/kind."""
231
232
@property
233
def title(self) -> str | None:
234
"""Optional section title."""
235
236
class DocstringElement:
237
"""
238
Base class for individual elements within docstring sections.
239
240
Represents discrete pieces of information within sections, such as
241
individual parameters, return values, or exceptions.
242
"""
243
244
def __init__(self, description: str = "") -> None:
245
"""
246
Initialize docstring element.
247
248
Args:
249
description: Element description text
250
"""
251
252
@property
253
def description(self) -> str:
254
"""Element description text."""
255
256
class DocstringNamedElement(DocstringElement):
257
"""
258
Base class for named docstring elements (parameters, attributes, etc.).
259
260
Extends DocstringElement with name and type annotation support
261
for elements that have identifiers.
262
"""
263
264
def __init__(
265
self,
266
name: str,
267
description: str = "",
268
annotation: str | None = None,
269
) -> None:
270
"""
271
Initialize named element.
272
273
Args:
274
name: Element name/identifier
275
description: Element description
276
annotation: Type annotation string
277
"""
278
279
@property
280
def name(self) -> str:
281
"""Element name."""
282
283
@property
284
def annotation(self) -> str | None:
285
"""Type annotation string."""
286
```
287
288
### Specific Element Types
289
290
Concrete implementations for different kinds of docstring elements.
291
292
```python { .api }
293
class DocstringParameter(DocstringNamedElement):
294
"""
295
Class representing parameter documentation in docstrings.
296
297
Used for function/method parameters with names, types, descriptions,
298
and default value information.
299
"""
300
301
def __init__(
302
self,
303
name: str,
304
description: str = "",
305
annotation: str | None = None,
306
default: str | None = None,
307
) -> None:
308
"""
309
Initialize parameter documentation.
310
311
Args:
312
name: Parameter name
313
description: Parameter description
314
annotation: Type annotation
315
default: Default value string
316
"""
317
318
@property
319
def default(self) -> str | None:
320
"""Default value string."""
321
322
class DocstringReturn(DocstringElement):
323
"""
324
Class representing return value documentation in docstrings.
325
326
Documents function return values with type and description information.
327
"""
328
329
def __init__(
330
self,
331
description: str = "",
332
annotation: str | None = None,
333
) -> None:
334
"""
335
Initialize return documentation.
336
337
Args:
338
description: Return value description
339
annotation: Return type annotation
340
"""
341
342
@property
343
def annotation(self) -> str | None:
344
"""Return type annotation."""
345
346
class DocstringRaise(DocstringNamedElement):
347
"""
348
Class representing exception/raise documentation in docstrings.
349
350
Documents exceptions that functions may raise with type and description.
351
"""
352
353
class DocstringYield(DocstringElement):
354
"""
355
Class representing yield documentation for generator functions.
356
357
Documents values yielded by generator functions.
358
"""
359
360
def __init__(
361
self,
362
description: str = "",
363
annotation: str | None = None,
364
) -> None:
365
"""
366
Initialize yield documentation.
367
368
Args:
369
description: Yield value description
370
annotation: Yield type annotation
371
"""
372
373
class DocstringAttribute(DocstringNamedElement):
374
"""
375
Class representing attribute documentation in docstrings.
376
377
Used for documenting class attributes, instance variables, and
378
module-level variables.
379
"""
380
381
class DocstringAdmonition(DocstringElement):
382
"""
383
Class representing admonition elements in docstrings.
384
385
Handles special notices like Note, Warning, See Also, etc.
386
"""
387
388
def __init__(
389
self,
390
kind: str,
391
description: str = "",
392
title: str | None = None,
393
) -> None:
394
"""
395
Initialize admonition.
396
397
Args:
398
kind: Admonition type (note, warning, etc.)
399
description: Admonition content
400
title: Optional custom title
401
"""
402
403
@property
404
def kind(self) -> str:
405
"""Admonition type."""
406
407
@property
408
def title(self) -> str | None:
409
"""Optional admonition title."""
410
```
411
412
### Section Types
413
414
Concrete section implementations for different docstring areas.
415
416
```python { .api }
417
class DocstringSectionParameters(DocstringSection):
418
"""Section containing function parameter documentation."""
419
420
def __init__(self, parameters: list[DocstringParameter]) -> None:
421
"""Initialize parameters section."""
422
423
@property
424
def parameters(self) -> list[DocstringParameter]:
425
"""List of documented parameters."""
426
427
class DocstringSectionReturns(DocstringSection):
428
"""Section containing return value documentation."""
429
430
def __init__(self, returns: list[DocstringReturn]) -> None:
431
"""Initialize returns section."""
432
433
@property
434
def returns(self) -> list[DocstringReturn]:
435
"""List of return value documentation."""
436
437
class DocstringSectionRaises(DocstringSection):
438
"""Section containing exception/raises documentation."""
439
440
def __init__(self, raises: list[DocstringRaise]) -> None:
441
"""Initialize raises section."""
442
443
@property
444
def raises(self) -> list[DocstringRaise]:
445
"""List of exception documentation."""
446
447
class DocstringSectionExamples(DocstringSection):
448
"""Section containing usage examples and code samples."""
449
450
def __init__(self, examples: list[tuple[str, str]]) -> None:
451
"""
452
Initialize examples section.
453
454
Args:
455
examples: List of (kind, text) tuples for examples
456
"""
457
458
@property
459
def examples(self) -> list[tuple[str, str]]:
460
"""List of examples as (kind, text) tuples."""
461
462
class DocstringSectionText(DocstringSection):
463
"""Section containing plain text content."""
464
465
def __init__(self, text: str) -> None:
466
"""Initialize text section."""
467
468
@property
469
def text(self) -> str:
470
"""Section text content."""
471
```
472
473
## Enumerations
474
475
```python { .api }
476
from enum import Enum
477
478
class DocstringStyle(Enum):
479
"""Enumeration of supported docstring styles."""
480
AUTO = "auto"
481
GOOGLE = "google"
482
NUMPY = "numpy"
483
SPHINX = "sphinx"
484
485
class DocstringDetectionMethod(Enum):
486
"""Enumeration of methods for automatically detecting docstring styles."""
487
HEURISTICS = "heuristics"
488
489
class DocstringSectionKind(Enum):
490
"""Enumeration of docstring section kinds."""
491
TEXT = "text"
492
PARAMETERS = "parameters"
493
OTHER_PARAMETERS = "other_parameters"
494
RETURNS = "returns"
495
YIELDS = "yields"
496
RECEIVES = "receives"
497
RAISES = "raises"
498
WARNS = "warns"
499
EXAMPLES = "examples"
500
ATTRIBUTES = "attributes"
501
FUNCTIONS = "functions"
502
CLASSES = "classes"
503
MODULES = "modules"
504
DEPRECATED = "deprecated"
505
ADMONITION = "admonition"
506
507
class Parser(Enum):
508
"""Enumeration of available docstring parsers."""
509
AUTO = "auto"
510
GOOGLE = "google"
511
NUMPY = "numpy"
512
SPHINX = "sphinx"
513
```
514
515
## Usage Examples
516
517
### Basic Docstring Parsing
518
519
```python
520
import griffe
521
522
# Parse with auto-detection
523
docstring_text = '''
524
Brief function description.
525
526
Args:
527
name (str): The person's name.
528
age (int, optional): The person's age. Defaults to 0.
529
530
Returns:
531
str: A greeting message.
532
533
Raises:
534
ValueError: If name is empty.
535
536
Example:
537
>>> greet("Alice", 25)
538
"Hello, Alice (age: 25)!"
539
'''
540
541
sections = griffe.parse_auto(docstring_text)
542
print(f"Found {len(sections)} sections:")
543
for section in sections:
544
print(f" - {section.kind.value}")
545
```
546
547
### Working with Parsed Sections
548
549
```python
550
import griffe
551
from griffe import DocstringSectionKind
552
553
# Parse a Google-style docstring
554
sections = griffe.parse_google(docstring_text)
555
556
# Find specific sections
557
for section in sections:
558
if section.kind == DocstringSectionKind.PARAMETERS:
559
print("Parameters:")
560
for param in section.parameters:
561
print(f" {param.name}: {param.annotation} - {param.description}")
562
if param.default:
563
print(f" Default: {param.default}")
564
565
elif section.kind == DocstringSectionKind.RETURNS:
566
print("Returns:")
567
for ret in section.returns:
568
print(f" {ret.annotation}: {ret.description}")
569
570
elif section.kind == DocstringSectionKind.RAISES:
571
print("Raises:")
572
for exc in section.raises:
573
print(f" {exc.name}: {exc.description}")
574
575
elif section.kind == DocstringSectionKind.EXAMPLES:
576
print("Examples:")
577
for kind, text in section.examples:
578
print(f" {kind}:")
579
print(f" {text}")
580
```
581
582
### Format Detection and Comparison
583
584
```python
585
import griffe
586
587
# Test different docstring styles
588
google_style = '''
589
Brief description.
590
591
Args:
592
param1: Description 1.
593
param2: Description 2.
594
595
Returns:
596
Something useful.
597
'''
598
599
numpy_style = '''
600
Brief description.
601
602
Parameters
603
----------
604
param1 : str
605
Description 1.
606
param2 : int
607
Description 2.
608
609
Returns
610
-------
611
bool
612
Something useful.
613
'''
614
615
sphinx_style = '''
616
Brief description.
617
618
:param param1: Description 1.
619
:type param1: str
620
:param param2: Description 2.
621
:type param2: int
622
:returns: Something useful.
623
:rtype: bool
624
'''
625
626
# Detect styles
627
styles = [
628
("Google", google_style),
629
("NumPy", numpy_style),
630
("Sphinx", sphinx_style)
631
]
632
633
for name, docstring in styles:
634
detected = griffe.infer_docstring_style(docstring)
635
print(f"{name} style detected as: {detected}")
636
637
# Parse with detected style
638
if detected:
639
sections = griffe.parse(docstring, parser=detected.value)
640
print(f" Parsed into {len(sections)} sections")
641
```
642
643
### Integration with Griffe Objects
644
645
```python
646
import griffe
647
648
# Load a module and parse its docstrings
649
module = griffe.load("requests")
650
651
# Find a function and parse its docstring
652
if "get" in module.functions:
653
get_func = module.functions["get"]
654
if get_func.docstring:
655
sections = get_func.docstring.parse(parser="auto")
656
657
print(f"Function: {get_func.name}")
658
print(f"Docstring sections: {[s.kind.value for s in sections]}")
659
660
# Extract parameter documentation
661
for section in sections:
662
if section.kind == griffe.DocstringSectionKind.PARAMETERS:
663
print("Documented parameters:")
664
for param in section.parameters:
665
print(f" {param.name}: {param.description}")
666
667
# Parse all function docstrings in module
668
for func_name, func in module.functions.items():
669
if func.docstring:
670
try:
671
sections = func.docstring.parse()
672
param_count = sum(
673
len(s.parameters) for s in sections
674
if s.kind == griffe.DocstringSectionKind.PARAMETERS
675
)
676
print(f"{func_name}: {param_count} documented parameters")
677
except Exception as e:
678
print(f"{func_name}: Failed to parse docstring - {e}")
679
```
680
681
### Custom Docstring Processing
682
683
```python
684
import griffe
685
from griffe import DocstringSectionKind
686
687
class DocstringAnalyzer:
688
"""Analyze docstring completeness and quality."""
689
690
def analyze_function(self, func: griffe.Function) -> dict:
691
"""Analyze a function's docstring."""
692
result = {
693
"has_docstring": func.docstring is not None,
694
"has_description": False,
695
"documented_params": 0,
696
"undocumented_params": 0,
697
"has_return_doc": False,
698
"has_examples": False,
699
"issues": []
700
}
701
702
if not func.docstring:
703
result["issues"].append("Missing docstring")
704
return result
705
706
# Parse the docstring
707
try:
708
sections = func.docstring.parse()
709
except Exception as e:
710
result["issues"].append(f"Failed to parse docstring: {e}")
711
return result
712
713
# Check for description
714
text_sections = [s for s in sections if s.kind == DocstringSectionKind.TEXT]
715
if text_sections and text_sections[0].text.strip():
716
result["has_description"] = True
717
718
# Check parameter documentation
719
param_sections = [s for s in sections if s.kind == DocstringSectionKind.PARAMETERS]
720
documented_param_names = set()
721
if param_sections:
722
for section in param_sections:
723
for param in section.parameters:
724
documented_param_names.add(param.name)
725
726
# Compare with actual parameters
727
actual_param_names = {p.name for p in func.parameters if p.name not in ("self", "cls")}
728
result["documented_params"] = len(documented_param_names)
729
result["undocumented_params"] = len(actual_param_names - documented_param_names)
730
731
# Check for undocumented parameters
732
undocumented = actual_param_names - documented_param_names
733
if undocumented:
734
result["issues"].append(f"Undocumented parameters: {', '.join(undocumented)}")
735
736
# Check return documentation
737
return_sections = [s for s in sections if s.kind == DocstringSectionKind.RETURNS]
738
result["has_return_doc"] = bool(return_sections)
739
740
# Check for examples
741
example_sections = [s for s in sections if s.kind == DocstringSectionKind.EXAMPLES]
742
result["has_examples"] = bool(example_sections)
743
744
return result
745
746
# Use the analyzer
747
analyzer = DocstringAnalyzer()
748
module = griffe.load("mypackage")
749
750
for func_name, func in module.functions.items():
751
analysis = analyzer.analyze_function(func)
752
print(f"\n{func_name}:")
753
print(f" Description: {'✓' if analysis['has_description'] else '✗'}")
754
print(f" Parameters: {analysis['documented_params']}/{analysis['documented_params'] + analysis['undocumented_params']}")
755
print(f" Return doc: {'✓' if analysis['has_return_doc'] else '✗'}")
756
print(f" Examples: {'✓' if analysis['has_examples'] else '✗'}")
757
758
if analysis["issues"]:
759
print(f" Issues: {'; '.join(analysis['issues'])}")
760
```
761
762
## Types
763
764
```python { .api }
765
from enum import Enum
766
from typing import Any
767
768
# Docstring parsing types
769
class DocstringStyle(Enum): ...
770
class DocstringDetectionMethod(Enum): ...
771
class DocstringSectionKind(Enum): ...
772
class Parser(Enum): ...
773
774
# Section and element base classes
775
class DocstringSection: ...
776
class DocstringElement: ...
777
class DocstringNamedElement(DocstringElement): ...
778
779
# Parser functions mapping
780
parsers: dict[str, callable]
781
```