Skip to main content

pydocstring-rs

PyPI - Version PyPI - Python Version Crates.io Version Crates.io MSRV

Python bindings for pydocstring — a zero-dependency Rust parser for Python docstrings (Google and NumPy styles).

Produces a unified syntax tree with byte-precise source locations on every token — designed as infrastructure for linters and formatters.

Features

  • Full syntax tree — builds a complete AST, not just extracted fields; traverse it with walk()
  • Typed objects per style — style-specific classes like GoogleArg, NumPyParameter
  • Byte-precise source locations — every token carries its exact byte range for pinpoint diagnostics
  • Powered by Rust — native extension with no Python runtime overhead
  • Error-resilient — never raises exceptions; malformed input still yields a best-effort tree
  • Style auto-detection — hand it a docstring, get back Style.GOOGLE, Style.NUMPY, or Style.PLAIN

Installation

pip install pydocstring-rs

Usage

Unified Parse (auto-detect)

Use parse() when you don't know the style in advance. The returned object has a .style property so you can dispatch without isinstance checks:

from pydocstring import parse, Style

doc = parse(source)

match doc.style:
    case Style.GOOGLE:
        for arg in doc.sections[0].args:
            print(arg.name.text, arg.description.text)
    case Style.NUMPY:
        for param in doc.sections[0].parameters:
            print([n.text for n in param.names], param.description.text)
    case Style.PLAIN:
        print(doc.summary.text)

When you only need the style-independent model, no dispatch is necessary:

model = parse(source).to_model()  # works for all three styles

If you already know the style, prefer the explicit functions parse_google(), parse_numpy(), or parse_plain() — they return a concrete type and are slightly more efficient.

Style Detection

from pydocstring import detect_style, Style

detect_style("Summary.\n\nArgs:\n    x: Desc.")       # Style.GOOGLE
detect_style("Summary.\n\nParameters\n----------\n")  # Style.NUMPY
detect_style("Just a summary.")                       # Style.PLAIN

Style.PLAIN covers docstrings with no recognised section markers: summary-only, summary + extended, and unrecognised styles such as Sphinx.

Plain Style

Docstrings with no NumPy or Google section markers are parsed as plain:

from pydocstring import parse_plain

doc = parse_plain("""Brief summary.

More detail here.
Spanning multiple lines.
""")

print(doc.summary.text)            # "Brief summary."
print(doc.extended_summary.text)   # "More detail here.\nSpanning multiple lines."

Unrecognised styles such as Sphinx are also treated as plain: the :param: lines are preserved verbatim in extended_summary.

Google Style

from pydocstring import parse_google

doc = parse_google("""Summary line.

Args:
    x (int): The first value.
    y (str): The second value.

Returns:
    bool: True if successful.

Raises:
    ValueError: If x is negative.
""")

# Summary
print(doc.summary.text)  # "Summary line."

# Sections
for section in doc.sections:
    print(section.section_kind)  # GoogleSectionKind.ARGS, .RETURNS, .RAISES

# Walk the tree to access entries
from pydocstring import walk, Visitor

class GoogleArgCollector(Visitor):
    def __init__(self): self.args = []
    def enter_google_arg(self, arg, ctx): self.args.append(arg)

for arg in walk(doc, GoogleArgCollector()).args:
    print(f"  {arg.name.text}: {arg.type.text}{arg.description.text}")

NumPy Style

from pydocstring import parse_numpy

doc = parse_numpy("""Summary line.

Parameters
----------
x : int
    The first value.
y : str
    The second value.

Returns
-------
bool
    True if successful.
""")

print(doc.summary.text)  # "Summary line."

for section in doc.sections:
    print(section.section_kind)  # NumPySectionKind.PARAMETERS, .RETURNS

# Walk the tree to access entries
class NumPyParamCollector(Visitor):
    def __init__(self): self.params = []
    def enter_numpy_parameter(self, p, ctx): self.params.append(p)

for param in walk(doc, NumPyParamCollector()).params:
    names = [n.text for n in param.names]
    print(f"  {names}: {param.type.text}{param.description.text}")

AST Access

Use pretty_print() to visualise the full syntax tree:

doc = parse_google("Summary.\n\nArgs:\n    x (int): Value.")

print(doc.pretty_print())

Output:

GOOGLE_DOCSTRING@0..42 {
  SUMMARY: "Summary."@0..8
  GOOGLE_SECTION@10..42 {
    GOOGLE_SECTION_HEADER@10..15 {
      NAME: "Args"@10..14
      COLON: ":"@14..15
    }
    GOOGLE_ARG@20..42 {
      NAME: "x"@20..21
      OPEN_BRACKET: "("@22..23
      TYPE: "int"@23..26
      CLOSE_BRACKET: ")"@26..27
      COLON: ":"@27..28
      DESCRIPTION: "Value."@29..35
    }
  }
}

Tree Traversal

Use walk() with a Visitor subclass for depth-first traversal. walk() returns the visitor instance so you can read results inline:

from pydocstring import parse_google, walk, Visitor

doc = parse_google("Summary.\n\nArgs:\n    x (int): Value.")

class NameCollector(Visitor):
    def __init__(self): self.names = []
    def enter_google_arg(self, arg, ctx): self.names.append(arg.name.text)

print(walk(doc, NameCollector()).names)  # ["x"]

WalkContext is passed as the second argument to every enter_* / exit_* hook and exposes line_col(offset) for O(log n) byte-offset-to-line/column conversion:

class LocPrinter(Visitor):
    def enter_google_arg(self, arg, ctx):
        lc = ctx.line_col(arg.name.range.start)
        print(f"{arg.name.text} at line {lc.lineno}, col {lc.col}")

walk(doc, LocPrinter())

Source Locations

All tokens carry byte-precise source ranges:

doc = parse_google("Summary.\n\nArgs:\n    x (int): Value.")
token = doc.summary
print(token.range.start, token.range.end)  # 0 8

Style-Independent Model (IR)

Convert any parsed docstring into a style-independent intermediate representation for analysis or transformation:

from pydocstring import parse_google, SectionKind

parsed = parse_google("Summary.\n\nArgs:\n    x (int): The value.\n")
doc = parsed.to_model()

print(doc.summary)  # "Summary."

for section in doc.sections:
    if section.kind == SectionKind.PARAMETERS:
        for param in section.parameters:
            print(param.names)            # ["x"]
            print(param.type_annotation)  # "int"
            print(param.description)      # "The value."

Emitting (Code Generation)

Re-emit a Docstring model in any style — useful for style conversion or formatting:

from pydocstring import Docstring, Section, SectionKind, Parameter, emit_google, emit_numpy

doc = Docstring(
    summary="Brief summary.",
    sections=[
        Section(
            SectionKind.PARAMETERS,
            parameters=[
                Parameter(
                    ["x"],
                    type_annotation="int",
                    description="The value.",
                ),
            ],
        ),
    ],
)

google = emit_google(doc)
print(google)  # Contains "Args:"

numpy = emit_numpy(doc)
print(numpy)  # Contains "Parameters\n----------"

Combine parsing and emitting to convert between styles:

from pydocstring import parse_google, emit_numpy

parsed = parse_google("Summary.\n\nArgs:\n    x (int): The value.\n")
doc = parsed.to_model()
numpy_text = emit_numpy(doc)
print(numpy_text)  # Contains "Parameters\n----------"

API Reference

Functions

Function Returns Description
parse(text) GoogleDocstring | NumPyDocstring | PlainDocstring Auto-detect style and parse
parse_google(text) GoogleDocstring Parse a Google-style docstring
parse_numpy(text) NumPyDocstring Parse a NumPy-style docstring
parse_plain(text) PlainDocstring Parse a plain docstring (no section markers)
detect_style(text) Style Detect style: Style.GOOGLE, Style.NUMPY, or Style.PLAIN
emit_google(doc) str Emit a Docstring model as Google-style text
emit_numpy(doc) str Emit a Docstring model as NumPy-style text

Objects

Class Key Properties
Style GOOGLE, NUMPY, PLAIN (enum)
GoogleSectionKind ARGS, RETURNS, YIELDS, RAISES, NOTES, EXAMPLES, … (enum)
NumPySectionKind PARAMETERS, RETURNS, YIELDS, RAISES, NOTES, EXAMPLES, … (enum)
GoogleDocstring style, summary, extended_summary, paragraphs, sections, deprecation, source, pretty_print(), to_model()
GoogleSection section_kind, header_name, range
GoogleArg name, type, description, optional, open_bracket, close_bracket, colon
GoogleReturn return_type, description, colon
GoogleYield return_type, description, colon
GoogleException type, description, colon
GoogleWarning type, description, colon
GoogleSeeAlsoItem name, description, colon
GoogleAttribute name, type, description, open_bracket, close_bracket, colon
GoogleMethod name, type, description, open_bracket, close_bracket, colon
PlainDocstring style, summary, extended_summary, source, pretty_print(), to_model()
NumPyDocstring style, summary, extended_summary, paragraphs, sections, deprecation, source, pretty_print(), to_model()
NumPySection section_kind, header_name, range
NumPyParameter name, names, type, description, optional, default_value, colon, default_keyword, default_separator
NumPyReturns name, return_type, description, colon
NumPyYields name, return_type, description, colon
NumPyException type, description, colon
NumPyWarning type, description, colon
NumPySeeAlsoItem name, description, colon
NumPyReference label, content, directive_marker, open_bracket, close_bracket
NumPyAttribute name, type, description, colon
NumPyMethod name, type, description, colon
NumPyDeprecation version, description, directive_marker, keyword, double_colon
Token text, range, is_missing()
TextRange start, end, is_empty()
Visitor Base class; subclass and override enter_* / exit_* methods
WalkContext line_col(offset) — passed as second arg to every enter_* / exit_* hook
SectionKind PARAMETERS, RETURNS, RAISES, NOTES, … (enum, 24 variants — model IR)
Docstring summary, extended_summary, directives, deprecation (computed), sections
Section (model) kind, parameters, returns, exceptions, attributes, methods, see_also_entries, references, body
Parameter names, type_annotation, description, is_optional, default_value
Return name, type_annotation, description
ExceptionEntry type_name, description
Attribute name, type_annotation, description
Method name, type_annotation, description
SeeAlsoEntry names, description
Reference label, content
Directive name, argument, description

Development

Prerequisites

  • Rust (stable)
  • uv (manages the Python interpreter, venv, and dev tooling)

Build

cd bindings/python

# Create the venv and install dev tooling (maturin, pytest) into it.
# uv provisions the pinned Python from .python-version automatically.
uv sync

# Build and install the native extension in development mode
uv run maturin develop --uv

# Verify
uv run python -c "import pydocstring; print(pydocstring.detect_style('Args:\n    x: y'))"

After changing the Rust source, re-run uv run maturin develop --uv to rebuild.

Build a wheel

uv run maturin build --release
# Output: target/wheels/pydocstring-*.whl

Publish to PyPI

uv run maturin publish

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pydocstring_rs-0.3.0.tar.gz (163.4 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pydocstring_rs-0.3.0-cp310-abi3-win_amd64.whl (393.3 kB view details)

Uploaded CPython 3.10+Windows x86-64

pydocstring_rs-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (584.8 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

pydocstring_rs-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (586.9 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

pydocstring_rs-0.3.0-cp310-abi3-macosx_11_0_arm64.whl (537.0 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

pydocstring_rs-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl (539.3 kB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

File details

Details for the file pydocstring_rs-0.3.0.tar.gz.

File metadata

  • Download URL: pydocstring_rs-0.3.0.tar.gz
  • Upload date:
  • Size: 163.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pydocstring_rs-0.3.0.tar.gz
Algorithm Hash digest
SHA256 24e0eb55d0a33129c425e3dc8074df44edd068b9c63b25d43029a6ed245c9cfd
MD5 b4c4bb1f5ac0ba5454a75dc9ae6179f3
BLAKE2b-256 63753f0c11b963123bbcdd7998f668d4978a4a8c729ddc381d9dd042d60371a9

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydocstring_rs-0.3.0.tar.gz:

Publisher: release.yml on ryumasai/pydocstring

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydocstring_rs-0.3.0-cp310-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for pydocstring_rs-0.3.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 af929e9812b5aaa7a3f1ba22829bb942ac270cb7b12d386d3f91cb547cb4beec
MD5 b8a198d9067733ee5dd409d1ee6edd16
BLAKE2b-256 21077a7e80befa1fc3b209a4b96c55b5691dedc796f7b3bd895f033816deb584

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydocstring_rs-0.3.0-cp310-abi3-win_amd64.whl:

Publisher: release.yml on ryumasai/pydocstring

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydocstring_rs-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pydocstring_rs-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 8077b6805a16cbb07c7025720f0cb2a95cf977465f4c36da75fbb18e5a769b06
MD5 1ead0df2461700e88deb5837fc9e8d09
BLAKE2b-256 628e5b497372ea0913cf3e7f870bd7d8ee34a5a23a9be2283b9b2f2131b5abba

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydocstring_rs-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on ryumasai/pydocstring

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydocstring_rs-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for pydocstring_rs-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 041a6f51b8c3af0dae8d42a25dcd020c7662918ca860dd0cd46ace5266951bfa
MD5 9c83d93dc8e8bae4f8be75a17e23eb47
BLAKE2b-256 3aa86eb16978c37bdb5dda8a65604d0adba1673e28476afb21e1a9f5608edc94

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydocstring_rs-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on ryumasai/pydocstring

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydocstring_rs-0.3.0-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pydocstring_rs-0.3.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b849cb395f661757fc1850e9ab43c60e4678c078419a249d103d34967657068a
MD5 64835420022b5ea13726605010cf18fe
BLAKE2b-256 963bcfa8e50902df5d79d2707e8a523b5b13a263d80593cb9f116878c2ae757d

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydocstring_rs-0.3.0-cp310-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on ryumasai/pydocstring

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydocstring_rs-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for pydocstring_rs-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 b7c7da537a71a099e6e053f1c90eb78733aec0cf3429c5e19b7fc4639ffd4f0c
MD5 451031f9f1e5f06f70765bf17e933521
BLAKE2b-256 5826475dfb315a70175263d6a1654cc0dbbf7cb3377565150c5c2cf8335a357a

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydocstring_rs-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl:

Publisher: release.yml on ryumasai/pydocstring

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page