Skip to content

Commit ea8ea35

Browse files
Cleanup
1 parent 15d47b7 commit ea8ea35

18 files changed

Lines changed: 551 additions & 298 deletions

.github/workflows/docs.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: docs
2+
3+
on:
4+
push:
5+
branches: [master]
6+
pull_request:
7+
8+
jobs:
9+
doctest:
10+
name: Documentation doctests
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- name: Install uv
16+
uses: astral-sh/setup-uv@v5
17+
18+
- name: Run documentation doctests
19+
run: >-
20+
uv run --extra docs --extra pandas --extra polars
21+
sphinx-build -b doctest docs/source docs/_build/doctest

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
__pycache__
22
old/
33
/docs/build
4+
/docs/_build
45
/docs/source/*
56
!/docs/source/*.rst
67
!/docs/source/conf.py

README.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ only pull in what you use:
4747
| `pandas` | `raffalib.pandas` accessors |
4848
| `polars` | `raffalib.polars` accessors and join logging |
4949
| `bibliometrics` | OpenAlex / Scopus helpers |
50-
| `crypto` | KeePassXC / GnuPG helpers |
5150
| `db` | SQLAlchemy view helpers |
5251
| `web` | Selenium helpers |
5352
| `docs` | Build the Sphinx documentation |
@@ -69,7 +68,7 @@ import raffalib.pandas # registers the `.raffa` accessor
6968

7069
logger = raffalib.create_logger(rich=False, fmt="{message}")
7170

72-
df = pd.read_csv("penguins.csv")
71+
df = pd.read_csv("https://raw.githubusercontent.com/allisonhorst/palmerpenguins/refs/heads/main/inst/extdata/penguins.csv")
7372

7473
# Shape changes are logged automatically
7574
_ = df.raffa.startlog().dropna(subset=["bill_depth_mm"]).raffa.endlog(timeit=False)
@@ -89,7 +88,7 @@ import raffalib.polars # registers the `.raffa` namespace
8988

9089
logger = raffalib.create_logger(rich=False, fmt="{message}")
9190

92-
df = pl.read_csv("penguins.csv")
91+
df = pl.read_csv("https://raw.githubusercontent.com/allisonhorst/palmerpenguins/refs/heads/main/inst/extdata/penguins.csv")
9392

9493
_ = df.raffa.startlog().filter(pl.col("species") == "Adelie").raffa.endlog(timeit=False)
9594
# -> Removed 192/344 (55.81%) rows.
@@ -153,6 +152,15 @@ uv run ruff check # lint
153152
uv run ruff format # format
154153
```
155154

155+
The examples in the documentation (`docs/source/quickstart.rst` and
156+
`examples.rst`) are executable doctests. They run in CI and can be checked
157+
locally with:
158+
159+
```console
160+
uv run --extra docs --extra pandas --extra polars \
161+
sphinx-build -b doctest docs/source docs/_build/doctest
162+
```
163+
156164
## License
157165

158166
Released under the [GNU General Public License v3.0 or later](LICENSE.txt).

docs/source/conf.py

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,53 @@
2626
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
2727

2828
extensions = [
29-
'autoapi.extension'
29+
'autoapi.extension',
30+
'sphinx.ext.doctest',
3031
]
3132

3233
autoapi_dirs = ['../../src']
3334

35+
# -- doctest configuration ---------------------------------------------------
36+
# The examples in the narrative docs are executable doctests, run with
37+
# ``sphinx-build -b doctest`` (``make doctest``). ELLIPSIS lets the
38+
# non-deterministic ``Took: ...`` timing lines match; NORMALIZE_WHITESPACE makes
39+
# the DataFrame/table reprs robust to incidental spacing differences.
40+
import doctest as _doctest
41+
42+
doctest_default_flags = _doctest.ELLIPSIS | _doctest.NORMALIZE_WHITESPACE
43+
44+
# Run once before every doctest group: import the libraries, route raffalib's
45+
# logging output to stdout so doctest can capture it (mirroring
46+
# ``create_logger(rich=False, fmt="{message}")``), and pin the table-rendering
47+
# width so the captured reprs are deterministic.
48+
doctest_global_setup = """
49+
import logging
50+
import numpy as np
51+
import pandas as pd
52+
import polars as pl
53+
import polars.selectors as cs
54+
import raffalib
55+
import raffalib.pandas
56+
import raffalib.polars
57+
58+
59+
class _DoctestLogHandler(logging.Handler):
60+
def emit(self, record):
61+
print(self.format(record))
62+
63+
64+
_handler = _DoctestLogHandler()
65+
_handler.setFormatter(logging.Formatter("%(message)s"))
66+
_raffalogger = logging.getLogger("raffalib")
67+
_raffalogger.handlers = [_handler]
68+
_raffalogger.setLevel(logging.INFO)
69+
_raffalogger.propagate = False
70+
71+
pd.set_option("display.max_columns", None)
72+
pd.set_option("display.width", 200)
73+
pl.Config(thousands_separator=",", tbl_cols=-1, tbl_width_chars=200)
74+
"""
75+
3476
# Document the class docstring and the __init__ docstring together.
3577
autoapi_python_class_content = "both"
3678

0 commit comments

Comments
 (0)