Skip to content

v0.1.6#15

Merged
qraqras merged 15 commits intomainfrom
dev
Mar 29, 2026
Merged

v0.1.6#15
qraqras merged 15 commits intomainfrom
dev

Conversation

@qraqras
Copy link
Copy Markdown
Owner

@qraqras qraqras commented Mar 29, 2026

No description provided.

qraqras added 15 commits March 24, 2026 06:52
…accessors

- Add GoogleSectionKind / NumPySectionKind enums
- Replace 22 typed *Section classes with unified GoogleSection /
  NumPySection carrying a section_kind property and per-kind accessor
  methods (args(), returns(), exceptions(), parameters(), ...)
- Add cast() classmethod to all 18 entry wrapper types
- Remove cast_google_* / cast_numpy_* methods from docstring classes
- Add missing entry wrappers: GoogleWarning, GoogleSeeAlsoItem,
  GoogleAttribute, GoogleMethod, NumPyDeprecation, NumPyWarning,
  NumPySeeAlsoItem, NumPyReference, NumPyAttribute, NumPyMethod
- Add deprecation() method to NumPyDocstring

BREAKING CHANGE: *Section typed wrapper classes removed; cast_* methods
on docstring objects removed; entry accessor methods are now callable
(section.args()) not indexable attributes.
- Rename GoogleReturns -> GoogleReturn, GoogleYields -> GoogleYield
  for consistency with singular naming convention
- Add parse::visitor module (DocstringVisitor, walk_node), re-exported
  from parse::google and parse::numpy
- Remove PySyntaxKind, PyNode, PyToken, PyDocstringWalker from the
  public Python API
- Replace collect_* / CST-walking helpers with typed builder functions
- Add walk() function with visitor dispatch pattern using Arc<Parsed>
- Reorder SyntaxKind: move PLAIN_DOCSTRING after NumPy variants
- Update .pyi stubs and tests to match new API
- Add WalkContext class exposing line_col(offset) and style
  to every visit_* method as a second argument
- All visit_* signatures change from (node) to (node, ctx: WalkContext)
- walk() now returns the visitor object (typed as _VisitorT in .pyi)
- Add visit_plain_docstring dispatch for PlainDocstring
- Add plain_docstring field to ActiveMethods / collect_active
- Replace dispatch() with dispatch_with_ctx() throughout
- Register PyWalkContext in the Python module
- Update .pyi stubs and tests (90 tests pass)
Add associated type Error to DocstringVisitor. All visit_* methods now
return Result<(), Self::Error>, and walk_node propagates errors via ?.

Infallible visitors use type Error = std::convert::Infallible.
Fallible visitors (e.g. PyO3 bindings) can use type Error = PyErr and
propagate Python exceptions directly without an error-accumulation field.

BREAKING CHANGE: all DocstringVisitor implementations must add
  type Error = ...;
and change visit_* signatures to return Result<(), Self::Error>.
…/leave)

- Remove walk_section, walk_node, walk_cst free functions
- Add PyDispatcher struct implementing core DocstringVisitor
  - Calls visit_* (enter) → core_walk_node → leave_* for all 21 node kinds
  - Supports leave_* callbacks alongside enter callbacks
- Thin PyGoogleSection / PyNumPySection (range, section_kind, header_name only)
- ActiveMethods / collect_active extended with 22 leave_* bool fields
- walk() entry point uses PyDispatcher for Google/NumPy trees
- Update tests to use walk-based API for accessing section children
- 90 Python tests pass
- Add pydocstring.Visitor base class (pure-Python, embedded in lib.rs)
  - All 46 enter_*/exit_* methods decorated with @_pydocstring_noop sentinel
  - __init_subclass__ computes __pydocstring_active__ frozenset at class
    definition time (zero per-instance cost, no super().__init__() required)
  - Visitor itself carries __pydocstring_active__ = frozenset() as a class var
- Update collect_active() fast path: extract frozenset in one PyO3 call,
  then use pure-Rust HashSet membership checks for all 50 method flags
- Remove duck-typing slow path: walk() now raises TypeError if visitor does
  not subclass Visitor (i.e. lacks __pydocstring_active__)
- Remove WalkContext.style (was redundant with the dispatched method name)
- Rename visitor methods: visit_*/leave_* -> enter_*/exit_* (ANTLR convention)
- Update pydocstring.pyi: add Visitor class with fully-typed method stubs,
  add bound="Visitor" to _VisitorT TypeVar
- Update tests: all Collector/Visitor classes now subclass pydocstring.Visitor
- Create python/pydocstring/ package (mixed Rust/Python maturin layout)
  - __init__.py: re-export ._pydocstring and ._visitor.Visitor
  - _visitor.py: Visitor base class (extracted from VISITOR_CLASS_CODE)
  - py.typed: PEP 561 marker
  - __init__.pyi: moved from pydocstring.pyi (type stubs)
- pyproject.toml: module-name="pydocstring._pydocstring", python-source="python"
- lib.rs: rename fn pydocstring -> fn _pydocstring, remove VISITOR_CLASS_CODE
  and Visitor registration block
- Fix GoogleDocstring/NumPyDocstring/PlainDocstring: pretty_print() and
  to_model() now use the cached Arc<Parsed> instead of re-parsing from
  source string each time.

- Add SectionKind enum (24 variants) to replace string-typed Section.kind.
  Section.__init__ now takes SectionKind instead of &str; Section.unknown_name
  getter exposes the original name for SectionKind.UNKNOWN entries.
  Remove now-unused free_section_kind_to_str / str_to_free_section_kind helpers.

- Add __all__ to __init__.py listing all public symbols.
…ction

Remove 19 non-existent child accessor properties from GoogleSection and
NumPySection that were present in the stubs but have no Rust implementation.
These classes are thin wrappers exposing only range, section_kind, and
header_name; child nodes must be accessed via walk().

Update docstrings on both classes to document this constraint.
… cache)

Remove line_col() from GoogleDocstring, NumPyDocstring, PlainDocstring.
WalkContext now builds a line-starts table (Vec<u32>) once at walk()
time and uses partition_point binary search, reducing per-call cost
from O(offset) to O(log L).

Update stubs and rewrite TestLineColumn / TestPlainDocstring line_col
tests to use ctx.line_col() via walk().
Add Token.is_missing() and TextRange.is_empty() to let callers detect
zero-length placeholder tokens inserted by the parser for syntactically
absent elements (e.g. empty brackets in a Google arg, colon-only NumPy
parameter).

Add mk_token_or_missing() helper that falls back to find_missing() when
find_token() returns None. Apply it to:
  - GoogleArg.type     (e.g. "x (): desc" => type.is_missing() == True)
  - NumPyParameter.type        (e.g. "x :" => type.is_missing() == True)
  - NumPyParameter.default_value  (separator present but value absent)

Without this change, missing and absent tokens were both None in Python,
making it impossible to distinguish "no brackets at all" from "empty
brackets".
Add all previously unexposed punctuation and structural token fields to
the Python bindings so that every token in the Rust parse tree is
accessible from Python.

Google nodes
- GoogleArg: +open_bracket, +close_bracket, +colon
- GoogleReturn: +colon
- GoogleYield: +colon
- GoogleException: +colon
- GoogleWarning: +colon
- GoogleSeeAlsoItem: +colon
- GoogleAttribute: +open_bracket, +close_bracket, +colon
- GoogleMethod: +open_bracket, +close_bracket, +colon

NumPy nodes
- NumPyDeprecation: +directive_marker, +keyword, +double_colon
- NumPyParameter: +colon, +default_keyword, +default_separator
- NumPyReturns: +colon
- NumPyYields: +colon
- NumPyException: +colon
- NumPyWarning: +colon
- NumPySeeAlsoItem: +colon
- NumPyReference: +directive_marker, +open_bracket, +close_bracket
- NumPyAttribute: +colon
- NumPyMethod: +colon

mk_token_or_missing is used where the parser inserts zero-length
placeholder tokens (GoogleArg/Attribute/Method type, close_bracket,
colon, description; NumPyParameter default_value).  All other new
fields use mk_token_opt.

Stubs updated accordingly.
- parse(): return ParsedDocstring enum instead of PyObject so the
  return type is self-documenting at the Rust level (stub already had
  the correct Union type)
- Token: add __eq__ and __hash__ so tokens can be used in sets/dicts
- Section.__init__: validate that kwargs match the section kind and
  raise TypeError for mismatches (mirrors Rust's compile-time enum safety)
@qraqras qraqras self-assigned this Mar 29, 2026
@qraqras qraqras merged commit b3b08e9 into main Mar 29, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant