Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Annotation Extraction

## Purpose
Extracts documentation and metadata from Python type annotations, enabling rich, inline documentation that is processed into standard docstring formats.

## Requirements

### Requirement: Doc Extraction
`Doc` objects embedded in `Annotated` types SHALL be extracted and used as documentation text.

Priority: Critical

#### Scenario: Single Doc Object
- **WHEN** an annotation is `Annotated[T, Doc("description")]`
- **THEN** "description" is extracted as the documentation text

#### Scenario: Multiple Doc Objects
- **WHEN** an annotation has multiple `Doc` objects
- **THEN** their contents are concatenated with proper spacing
- **AND** multiline descriptions are indented correctly

### Requirement: Raises Documentation
`Raises` annotations in return types SHALL document exceptions that may be raised.

Priority: Critical

#### Scenario: Single Exception
- **WHEN** the return annotation includes `Raises(ExceptionClass, "description")`
- **THEN** a `:raises ExceptionClass:` field is generated with the description

#### Scenario: Multiple Exceptions
- **WHEN** multiple `Raises` annotations are present
- **THEN** each is processed independently and added to the docstring

#### Scenario: Exception Sequence
- **WHEN** `Raises` is initialized with a sequence of exception classes
- **THEN** they are documented as a Union of exceptions

### Requirement: Complex Type Reduction
Complex generic types SHALL be reduced to a readable format for documentation.

Priority: High

#### Scenario: Union Types
- **WHEN** a type is `Union[A, B]` or `A | B`
- **THEN** it is rendered as `A | B` in the documentation

#### Scenario: Generic Types
- **WHEN** a type is `Container[ElementType]`
- **THEN** it is rendered with its generic arguments recursively reduced

#### Scenario: Forward References
- **WHEN** a type is a `ForwardRef` or string annotation
- **THEN** it is rendered as the string representation
- **AND** infinite recursion from cycles is prevented via cache

### Requirement: Cycle Detection
The system SHALL detect and handle reference cycles in annotations.

Priority: Critical

#### Scenario: Recursive Types
- **WHEN** a type definition refers to itself
- **THEN** infinite recursion is prevented
- **AND** the type is represented as `Any` or a string reference in documentation

### Requirement: Malformed Annotation Handling
The system SHALL handle invalid or malformed annotations gracefully.

Priority: High

#### Scenario: Invalid Metadata
- **WHEN** annotation metadata is invalid (e.g., non-Doc object where expected)
- **THEN** a warning is issued via the notifier
- **AND** the process continues without crashing
82 changes: 82 additions & 0 deletions documentation/architecture/openspec/specs/core-decoration/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Core Decoration

## Purpose
Enables automatic documentation generation for functions, classes, and modules by decorating them or explicitly assigning docstrings. It bridges the gap between Python's rich type annotations and documentation tools like Sphinx, ensuring that documentation lives alongside the code it describes.

## Requirements

### Requirement: Function Decoration
The `@with_docstring()` decorator SHALL generate parameter and return documentation from function annotations and assign it to the function's `__doc__` attribute.

Priority: Critical

#### Scenario: Basic Function Decoration
- **WHEN** a function is decorated with `@with_docstring()`
- **AND** the function has `Annotated` parameters with `Doc` metadata
- **THEN** the function's `__doc__` attribute contains Sphinx-formatted parameter documentation
- **AND** existing docstring content is preserved if `preserve=True`

#### Scenario: Keyword-only and Variadic Parameters
- **WHEN** a function has keyword-only or variadic parameters (`*args`, `**kwargs`)
- **THEN** they are correctly documented in the generated docstring

### Requirement: Class Decoration
The `@with_docstring()` decorator SHALL document class and instance attributes from class annotations when applied to a class.

Priority: Critical

#### Scenario: Class Attribute Documentation
- **WHEN** a class is decorated with `@with_docstring()`
- **AND** the class has `Annotated` attributes with `Doc` metadata
- **THEN** class variables are documented as `:cvar:`
- **AND** instance variables are documented as `:ivar:`

#### Scenario: Property Documentation
- **WHEN** a class has a property with a getter
- **THEN** the property is documented based on the getter's docstring and signature

### Requirement: Module Documentation
The `assign_module_docstring()` function SHALL document module-level attributes from module annotations.

Priority: Critical

#### Scenario: Module Attribute Documentation
- **WHEN** `assign_module_docstring(module)` is called
- **THEN** annotated module-level variables are documented
- **AND** `TypeAlias` annotations are documented as `:py:type:`
- **AND** other variables are documented as `:py:data:`

#### Scenario: Visibility Respect
- **WHEN** the module has `__all__` defined
- **THEN** only attributes listed in `__all__` are documented by default

### Requirement: Default Value Handling
The system SHALL allow controlling how default values are documented via `Default` metadata.

Priority: Medium

#### Scenario: Suppress Default Value
- **WHEN** an argument has `Default(mode=ValuationModes.Suppress)`
- **THEN** the default value is omitted from the generated documentation

#### Scenario: Surrogate Default Value
- **WHEN** an argument has `Default(mode=ValuationModes.Surrogate, surrogate="value")`
- **THEN** "value" is shown as the default in the documentation

### Requirement: Decoration Safety
The system SHALL prevent multiple decoration of the same object and ensure minimal overhead.

Priority: Critical

#### Scenario: Multiple Decoration Prevention
- **WHEN** an object is decorated multiple times
- **THEN** it is processed only once (idempotency)

### Requirement: Sphinx Compatibility
Generated docstrings SHALL be compatible with Sphinx Autodoc.

Priority: Critical

#### Scenario: Sphinx Parsing
- **WHEN** generated docstrings are parsed by Sphinx
- **THEN** they render correctly without syntax errors
48 changes: 48 additions & 0 deletions documentation/architecture/openspec/specs/customization/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Customization

## Purpose
Provides extension points for users to customize the output format, manage reusable content, and configure the documentation generation process.

## Requirements

### Requirement: Custom Renderers
Custom renderers SHALL be capable of generating documentation in formats other than Sphinx reStructuredText.

Priority: High

#### Scenario: Renderer Protocol
- **WHEN** a custom renderer matching the `Renderer` protocol is provided
- **THEN** it receives introspection data and context
- **AND** its output is used as the generated docstring

### Requirement: Fragment Tables
Reusable documentation fragments SHALL be definable and referenced from multiple locations.

Priority: Medium

#### Scenario: Fragment Reference
- **WHEN** a string annotation matches a key in the `FragmentsTable`
- **THEN** the corresponding value from the table is used in the documentation

#### Scenario: Missing Fragment
- **WHEN** a fragment name is not found in the table
- **THEN** an error is reported via the notifier

### Requirement: Context Configuration
`Context` objects SHALL configure and customize the documentation generation process.

Priority: High

#### Scenario: Context Customization
- **WHEN** `produce_context()` is called with custom components (notifier, rectifier)
- **THEN** a `Context` object is created with those customizations
- **AND** the context is immutable to prevent accidental modification

### Requirement: Extension Protocols
The system SHALL provide protocols for custom components.

Priority: High

#### Scenario: Custom Implementation
- **WHEN** a user implements `Renderer`, `Notifier`, `VisibilityDecider`, or `FragmentRectifier` protocols
- **THEN** the system accepts and uses the custom implementation
45 changes: 45 additions & 0 deletions documentation/architecture/openspec/specs/introspection/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Introspection

## Purpose
Controls the scope and depth of documentation generation, allowing users to define what gets documented and how visibility rules are applied.

## Requirements

### Requirement: Visibility Control
Attribute visibility SHALL be controlled to hide internal implementation details or force documentation of specific members.

Priority: High

#### Scenario: Conceal Visibility
- **WHEN** an attribute has `Visibilities.Conceal` annotation
- **THEN** it is excluded from the generated documentation

#### Scenario: Reveal Visibility
- **WHEN** an attribute has `Visibilities.Reveal` annotation
- **THEN** it is included in the generated documentation even if private

#### Scenario: Custom Visibility Decider
- **WHEN** a custom `VisibilityDecider` is provided in the context
- **THEN** it determines visibility based on the possessor, name, and annotation

### Requirement: Introspection Control
Introspection configuration SHALL control which object types are recursively documented and the documentation scope.

Priority: Medium

#### Scenario: Target Selection
- **WHEN** `IntrospectionControl.targets` includes `Module`
- **THEN** submodules matching the package prefix are recursively documented

#### Scenario: Recursion Limit
- **WHEN** an object defines `_dynadoc_introspection_limit_`
- **THEN** recursion depth and targets are limited for that object's subtree

### Requirement: Custom Introspectors
The system SHALL support custom introspectors for special class types.

Priority: Medium

#### Scenario: Special Class Introspection
- **WHEN** a class has special structure (e.g., Enum, dataclass)
- **THEN** a registered custom introspector can handle it
Loading