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
1 change: 1 addition & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ jobs:
- sphinx-autodoc-docutils
- sphinx-autodoc-sphinx
- sphinx-autodoc-pytest-fixtures
- sphinx-autodoc-api-style
steps:
- uses: actions/checkout@v6

Expand Down
6 changes: 3 additions & 3 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ $ uv add gp-sphinx --prerelease allow
Furo code blocks use 300, and intermediate weights inherit from
surrounding context — previously only Sans had the full set)
- Replace `font-weight: 650` with `700` in badge CSS across
`sphinx-autodoc-pytest-fixtures`, `sphinx-gptheme`, and docs (650 is not
a standard Fontsource weight, so browsers were synthesizing bold instead
of using the real font file)
`sphinx-autodoc-api-style`, `sphinx-autodoc-pytest-fixtures`,
`sphinx-gptheme`, and docs (650 is not a standard Fontsource weight,
so browsers were synthesizing bold instead of using the real font file)

### Workspace packages

Expand Down
187 changes: 187 additions & 0 deletions docs/_ext/gas_demo_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
"""Synthetic Python objects for the sphinx_autodoc_api_style badge demo page.

Each object exercises one badge combination so the demo page can show
every type and modifier badge side-by-side:

Types: function | class | method | property | attribute | data | exception
Modifiers: async | classmethod | staticmethod | abstract | final | deprecated

These definitions are purely for documentation; they are never used in
production code.
"""

from __future__ import annotations

import abc
import typing as t


def demo_function(name: str, count: int = 1) -> list[str]:
"""Plain function. Shows ``function`` type badge.

Parameters
----------
name : str
The name to repeat.
count : int
Number of repetitions.

Returns
-------
list[str]
A list of repeated names.
"""
return [name] * count


async def demo_async_function(url: str) -> bytes:
"""Asynchronous function. Shows ``async`` + ``function`` badges.

Parameters
----------
url : str
The URL to fetch.

Returns
-------
bytes
The fetched content.
"""
return b""


def demo_deprecated_function() -> None:
"""Do nothing (deprecated placeholder).

Shows ``deprecated`` + ``function`` badges.

.. deprecated:: 2.0
Use :func:`demo_function` instead.
"""


DEMO_CONSTANT: int = 42
"""Module-level constant. Shows ``data`` type badge."""


class DemoError(Exception):
"""Custom exception class. Shows ``exception`` type badge.

Raised when a demo operation fails unexpectedly.
"""


class DemoClass:
"""Demonstration class with various method types.

Shows ``class`` type badge on the class itself, and per-method
badges for each method kind.

Parameters
----------
value : str
Initial value for the demo instance.
"""

demo_attr: str = "hello"
"""Class attribute. Shows ``attribute`` type badge."""

def __init__(self, value: str) -> None:
self.value = value

def regular_method(self, x: int) -> str:
"""Regular instance method. Shows ``method`` type badge.

Parameters
----------
x : int
Input value.

Returns
-------
str
String representation.
"""
return f"{self.value}:{x}"

@classmethod
def from_int(cls, n: int) -> DemoClass:
"""Class method. Shows ``classmethod`` + ``method`` badges.

Parameters
----------
n : int
Integer to convert.

Returns
-------
DemoClass
A new instance.
"""
return cls(str(n))

@staticmethod
def utility(a: int, b: int) -> int:
"""Add two integers. Shows ``staticmethod`` + ``method`` badges.

Parameters
----------
a : int
First operand.
b : int
Second operand.

Returns
-------
int
Sum of operands.
"""
return a + b

@property
def computed(self) -> str:
"""Computed property. Shows ``property`` type badge.

Returns
-------
str
The uppercased value.
"""
return self.value.upper()

async def async_method(self) -> None:
"""Asynchronous method. Shows ``async`` + ``method`` badges."""

def deprecated_method(self) -> None:
"""Do nothing (deprecated placeholder).

Shows ``deprecated`` + ``method`` badges.

.. deprecated:: 1.5
Use :meth:`regular_method` instead.
"""


class DemoAbstractBase(abc.ABC):
"""Abstract base class. Shows ``class`` type badge.

Subclass this to provide concrete implementations.
"""

@abc.abstractmethod
def must_implement(self) -> str:
"""Abstract method. Shows ``abstract`` + ``method`` badges.

Returns
-------
str
Implementation-specific value.
"""

@abc.abstractmethod
async def async_abstract(self) -> None:
"""Async abstract method. Shows ``async`` + ``abstract`` + ``method`` badges."""


if t.TYPE_CHECKING:
DemoAlias = str | int
2 changes: 2 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
)
sys.path.insert(0, str(project_root / "packages" / "sphinx-autodoc-docutils" / "src"))
sys.path.insert(0, str(project_root / "packages" / "sphinx-autodoc-sphinx" / "src"))
sys.path.insert(0, str(project_root / "packages" / "sphinx-autodoc-api-style" / "src"))
sys.path.insert(0, str(cwd / "_ext")) # docs demo modules

import gp_sphinx # noqa: E402
Expand All @@ -37,6 +38,7 @@
source_branch="main",
extra_extensions=[
"package_reference",
"sphinx_autodoc_api_style",
"sphinx_autodoc_pytest_fixtures",
"sphinx_autodoc_docutils",
"sphinx_autodoc_sphinx",
Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Install and get started in minutes.
:::{grid-item-card} Packages
:link: packages/index
:link-type: doc
Seven workspace packages — coordinator, extensions, and theme.
Eight workspace packages — coordinator, extensions, and theme.
:::

:::{grid-item-card} Configuration
Expand Down
3 changes: 2 additions & 1 deletion docs/packages/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Packages

Seven workspace packages, each independently installable.
Eight workspace packages, each independently installable.

```{workspace-package-grid}
```
Expand All @@ -9,6 +9,7 @@ Seven workspace packages, each independently installable.
:hidden:

gp-sphinx
sphinx-autodoc-api-style
sphinx-autodoc-docutils
sphinx-autodoc-sphinx
sphinx-autodoc-pytest-fixtures
Expand Down
131 changes: 131 additions & 0 deletions docs/packages/sphinx-autodoc-api-style.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
(sphinx-autodoc-api-style)=

# sphinx-autodoc-api-style

{bdg-warning-line}`Alpha` {bdg-link-secondary-line}`GitHub <https://github.com/git-pull/gp-sphinx/tree/main/packages/sphinx-autodoc-api-style>` {bdg-link-secondary-line}`PyPI <https://pypi.org/project/sphinx-autodoc-api-style/>`

Sphinx extension that adds type and modifier badges to standard Python domain
entries (functions, classes, methods, properties, attributes, data,
exceptions). Mirrors the badge system from
{doc}`sphinx-autodoc-pytest-fixtures` so API pages and fixture pages share a
consistent visual language.

```console
$ pip install sphinx-autodoc-api-style
```

## Features

- **Type badges** (rightmost): `function`, `class`, `method`, `property`,
`attribute`, `data`, `exception` — each with a distinct color
- **Modifier badges** (left of type): `async`, `classmethod`, `staticmethod`,
`abstract`, `final`, `deprecated`
- **Card containers**: bordered cards with secondary-background headers
- **Dark mode**: full light/dark theming via CSS custom properties
- **Accessibility**: keyboard-focusable badges with tooltip popups
- **Non-invasive**: hooks into `doctree-resolved` without replacing directives

## How it works

Add `sphinx_autodoc_api_style` to your Sphinx extensions. With `gp-sphinx`,
use `extra_extensions`:

```python
conf = merge_sphinx_config(
project="my-project",
version="1.0.0",
copyright="2026, Your Name",
source_repository="https://github.com/your-org/my-project/",
extra_extensions=["sphinx_autodoc_api_style"],
)
```

Or without `merge_sphinx_config`:

```python
extensions = ["sphinx_autodoc_api_style"]
```

No special directives are needed — existing `.. autofunction::`,
`.. autoclass::`, `.. automodule::` directives automatically receive badges.

## Live demo

```{py:module} gas_demo_api
```

### Functions

```{eval-rst}
.. autofunction:: gas_demo_api.demo_function
```

```{eval-rst}
.. autofunction:: gas_demo_api.demo_async_function
```

```{eval-rst}
.. autofunction:: gas_demo_api.demo_deprecated_function
```

### Module data

```{eval-rst}
.. autodata:: gas_demo_api.DEMO_CONSTANT
```

### Exceptions

```{eval-rst}
.. autoexception:: gas_demo_api.DemoError
```

### Classes

```{eval-rst}
.. autoclass:: gas_demo_api.DemoClass
:members:
:undoc-members:
```

### Abstract base classes

```{eval-rst}
.. autoclass:: gas_demo_api.DemoAbstractBase
:members:
```

## Badge reference

### Type badges

| Object type | CSS class | Color |
|-------------|-----------|-------|
| `function` | `gas-type-function` | Blue |
| `class` | `gas-type-class` | Indigo |
| `method` | `gas-type-method` | Cyan |
| `property` | `gas-type-property` | Teal |
| `attribute` | `gas-type-attribute` | Slate |
| `data` | `gas-type-data` | Grey |
| `exception` | `gas-type-exception` | Rose |

### Modifier badges

| Modifier | CSS class | Style |
|----------|-----------|-------|
| `async` | `gas-mod-async` | Purple outlined |
| `classmethod` | `gas-mod-classmethod` | Amber outlined |
| `staticmethod` | `gas-mod-staticmethod` | Grey outlined |
| `abstract` | `gas-mod-abstract` | Indigo outlined |
| `final` | `gas-mod-final` | Emerald outlined |
| `deprecated` | `gas-deprecated` | Red/grey outlined |

## CSS prefix

All CSS classes use the `gas-` prefix (**g**p-sphinx **a**pi **s**tyle) to avoid
collision with `spf-` (sphinx pytest fixtures) or other extensions.

```{package-reference} sphinx-autodoc-api-style
```

[Source on GitHub](https://github.com/git-pull/gp-sphinx/tree/main/packages/sphinx-autodoc-api-style) · [PyPI](https://pypi.org/project/sphinx-autodoc-api-style/)
1 change: 1 addition & 0 deletions docs/redirects.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ extensions/sphinx-argparse-neo packages/sphinx-argparse-neo
extensions/sphinx-autodoc-pytest-fixtures packages/sphinx-autodoc-pytest-fixtures
extensions/sphinx-autodoc-docutils packages/sphinx-autodoc-docutils
extensions/sphinx-autodoc-sphinx packages/sphinx-autodoc-sphinx
extensions/sphinx-autodoc-api-style packages/sphinx-autodoc-api-style
extensions/sphinx-fonts packages/sphinx-fonts
extensions/sphinx-gptheme packages/sphinx-gptheme
Loading