From c633800ce24e4a12e9ddd4cc7df3cf53974c1c8e Mon Sep 17 00:00:00 2001 From: Manish Kumar Date: Sun, 17 May 2026 00:29:11 +0200 Subject: [PATCH 1/7] =?UTF-8?q?build:=20upgrade=20Sphinx=206.2.1=20?= =?UTF-8?q?=E2=86=92=209.1.0,=20update=20RTD=20and=20lock=20file?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docs.yml | 4 +- poetry.lock | 280 ++++++++++++++++++++----------------- pyproject.toml | 14 +- readthedocs.yaml | 4 +- 4 files changed, 162 insertions(+), 140 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index e6fdb37..4c6ce14 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -37,7 +37,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.10" + python-version: "3.12" - name: Install Poetry run: pipx install poetry @@ -49,7 +49,7 @@ jobs: uses: actions/cache@v4 with: path: .venv - key: venv-docs-${{ runner.os }}-3.10-${{ hashFiles('poetry.lock') }} + key: venv-docs-${{ runner.os }}-3.12-${{ hashFiles('poetry.lock') }} - name: Install package and docs dependencies run: poetry install --with docs diff --git a/poetry.lock b/poetry.lock index 99b04ff..419b713 100644 --- a/poetry.lock +++ b/poetry.lock @@ -834,11 +834,25 @@ description = "Docutils -- Python Documentation Utilities" optional = false python-versions = ">=3.7" groups = ["dev", "docs"] +markers = "python_version == \"3.10\"" files = [ {file = "docutils-0.19-py3-none-any.whl", hash = "sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc"}, {file = "docutils-0.19.tar.gz", hash = "sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6"}, ] +[[package]] +name = "docutils" +version = "0.22.4" +description = "Docutils -- Python Documentation Utilities" +optional = false +python-versions = ">=3.9" +groups = ["dev", "docs"] +markers = "python_version >= \"3.11\"" +files = [ + {file = "docutils-0.22.4-py3-none-any.whl", hash = "sha256:d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de"}, + {file = "docutils-0.22.4.tar.gz", hash = "sha256:4db53b1fde9abecbb74d91230d32ab626d94f6badfc575d6db9194a49df29968"}, +] + [[package]] name = "einops" version = "0.8.1" @@ -1814,46 +1828,30 @@ files = [ [package.dependencies] lxml = "*" -[[package]] -name = "m2r2" -version = "0.3.3.post2" -description = "Markdown and reStructuredText in a single file." -optional = false -python-versions = ">=3.7" -groups = ["docs"] -files = [ - {file = "m2r2-0.3.3.post2-py3-none-any.whl", hash = "sha256:86157721eb6eabcd54d4eea7195890cc58fa6188b8d0abea633383cfbb5e11e3"}, - {file = "m2r2-0.3.3.post2.tar.gz", hash = "sha256:e62bcb0e74b3ce19cda0737a0556b04cf4a43b785072fcef474558f2c1482ca8"}, -] - -[package.dependencies] -docutils = ">=0.19" -mistune = "0.8.4" - [[package]] name = "markdown-it-py" -version = "3.0.0" +version = "4.2.0" description = "Python port of markdown-it. Markdown parsing, done right!" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" groups = ["dev", "docs"] files = [ - {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, - {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, + {file = "markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a"}, + {file = "markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49"}, ] +markers = {docs = "python_version >= \"3.12\""} [package.dependencies] mdurl = ">=0.1,<1.0" [package.extras] benchmarking = ["psutil", "pytest", "pytest-benchmark"] -code-style = ["pre-commit (>=3.0,<4.0)"] -compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] +compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "markdown-it-pyrs", "mistletoe (>=1.0,<2.0)", "mistune (>=3.0,<4.0)", "panflute (>=2.3,<3.0)"] linkify = ["linkify-it-py (>=1,<3)"] -plugins = ["mdit-py-plugins"] +plugins = ["mdit-py-plugins (>=0.5.0)"] profiling = ["gprof2dot"] -rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] -testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] +rtd = ["ipykernel", "jupyter_sphinx", "mdit-py-plugins (>=0.5.0)", "myst-parser", "pyyaml", "sphinx", "sphinx-book-theme (>=1.0,<2.0)", "sphinx-copybutton", "sphinx-design"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions", "pytest-timeout", "requests"] [[package]] name = "markupsafe" @@ -1946,14 +1944,15 @@ test = ["flake8", "nbdime", "nbval", "notebook", "pytest"] [[package]] name = "mdit-py-plugins" -version = "0.5.0" +version = "0.6.1" description = "Collection of plugins for markdown-it-py" optional = false python-versions = ">=3.10" groups = ["docs"] +markers = "python_version >= \"3.12\"" files = [ - {file = "mdit_py_plugins-0.5.0-py3-none-any.whl", hash = "sha256:07a08422fc1936a5d26d146759e9155ea466e842f5ab2f7d2266dd084c8dab1f"}, - {file = "mdit_py_plugins-0.5.0.tar.gz", hash = "sha256:f4918cb50119f50446560513a8e311d574ff6aaed72606ddae6d35716fe809c6"}, + {file = "mdit_py_plugins-0.6.1-py3-none-any.whl", hash = "sha256:214c82fb2ac524472ab6a5bcab1de80f73b50443e187f401bfd77efbc7c6481d"}, + {file = "mdit_py_plugins-0.6.1.tar.gz", hash = "sha256:a2bca0f039f39dbd35fb74ae1b5f998608c437463371f0ff7f49a19a17a114d0"}, ] [package.dependencies] @@ -1962,7 +1961,7 @@ markdown-it-py = ">=2.0.0,<5.0.0" [package.extras] code-style = ["pre-commit"] rtd = ["myst-parser", "sphinx-book-theme"] -testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions", "pytest-timeout"] [[package]] name = "mdurl" @@ -1975,6 +1974,7 @@ files = [ {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, ] +markers = {docs = "python_version >= \"3.12\""} [[package]] name = "mistune" @@ -2126,30 +2126,31 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.11\""} [[package]] name = "myst-parser" -version = "3.0.1" +version = "5.1.0" description = "An extended [CommonMark](https://spec.commonmark.org/) compliant parser," optional = false -python-versions = ">=3.8" +python-versions = ">=3.11" groups = ["docs"] +markers = "python_version >= \"3.12\"" files = [ - {file = "myst_parser-3.0.1-py3-none-any.whl", hash = "sha256:6457aaa33a5d474aca678b8ead9b3dc298e89c68e67012e73146ea6fd54babf1"}, - {file = "myst_parser-3.0.1.tar.gz", hash = "sha256:88f0cb406cb363b077d176b51c476f62d60604d68a8dcdf4832e080441301a87"}, + {file = "myst_parser-5.1.0-py3-none-any.whl", hash = "sha256:9c91c52b3cdb4d94a6506e4fab4e2f296c7623a0da0dcbe6de1565c3dad67a8a"}, + {file = "myst_parser-5.1.0.tar.gz", hash = "sha256:ab69322dc6719dcc7f296479dbb70181b66df6ed315064f92dbc85c0e1bf2f02"}, ] [package.dependencies] -docutils = ">=0.18,<0.22" +docutils = ">=0.20,<0.23" jinja2 = "*" -markdown-it-py = ">=3.0,<4.0" -mdit-py-plugins = ">=0.4,<1.0" +markdown-it-py = ">=4.2,<5.0" +mdit-py-plugins = ">=0.6.1,<1.0" pyyaml = "*" -sphinx = ">=6,<8" +sphinx = ">=8,<10" [package.extras] -code-style = ["pre-commit (>=3.0,<4.0)"] +code-style = ["pre-commit (>=4.0,<5.0)"] linkify = ["linkify-it-py (>=2.0,<3.0)"] -rtd = ["ipython", "sphinx (>=7)", "sphinx-autodoc2 (>=0.5.0,<0.6.0)", "sphinx-book-theme (>=1.1,<2.0)", "sphinx-copybutton", "sphinx-design", "sphinx-pyscript", "sphinx-tippy (>=0.4.3)", "sphinx-togglebutton", "sphinxext-opengraph (>=0.9.0,<0.10.0)", "sphinxext-rediraffe (>=0.2.7,<0.3.0)"] -testing = ["beautifulsoup4", "coverage[toml]", "defusedxml", "pytest (>=8,<9)", "pytest-cov", "pytest-param-files (>=0.6.0,<0.7.0)", "pytest-regressions", "sphinx-pytest"] -testing-docutils = ["pygments", "pytest (>=8,<9)", "pytest-param-files (>=0.6.0,<0.7.0)"] +rtd = ["ipython", "sphinx (>=8)", "sphinx-autodoc2 (>=0.5.0,<0.6.0)", "sphinx-book-theme (>=1.1,<2.0)", "sphinx-copybutton", "sphinx-design", "sphinx-pyscript", "sphinx-tippy (>=0.4.3)", "sphinx-togglebutton", "sphinxext-opengraph (>=0.13.0,<0.14.0)", "sphinxext-rediraffe (>=0.3.0,<0.4.0)"] +testing = ["beautifulsoup4", "coverage[toml]", "defusedxml", "pygments (<2.21)", "pytest (>=9,<10)", "pytest-cov", "pytest-param-files (>=0.6.0,<0.7.0)", "pytest-regressions", "sphinx-pytest (>=0.3.0,<0.4.0)"] +testing-docutils = ["pygments", "pytest (>=9,<10)", "pytest-param-files (>=0.6.0,<0.7.0)"] [[package]] name = "nbclient" @@ -2476,26 +2477,20 @@ files = [ [[package]] name = "numpydoc" -version = "1.7.0" +version = "1.10.0" description = "Sphinx extension to support docstrings in Numpy format" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" groups = ["docs"] files = [ - {file = "numpydoc-1.7.0-py3-none-any.whl", hash = "sha256:5a56419d931310d79a06cfc2a126d1558700feeb9b4f3d8dcae1a8134be829c9"}, - {file = "numpydoc-1.7.0.tar.gz", hash = "sha256:866e5ae5b6509dcf873fc6381120f5c31acf13b135636c1a81d68c166a95f921"}, + {file = "numpydoc-1.10.0-py3-none-any.whl", hash = "sha256:3149da9874af890bcc2a82ef7aae5484e5aa81cb2778f08e3c307ba6d963721b"}, + {file = "numpydoc-1.10.0.tar.gz", hash = "sha256:3f7970f6eee30912260a6b31ac72bba2432830cd6722569ec17ee8d3ef5ffa01"}, ] [package.dependencies] sphinx = ">=6" -tabulate = ">=0.8.10" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -[package.extras] -developer = ["pre-commit (>=3.3)", "tomli ; python_version < \"3.11\""] -doc = ["matplotlib (>=3.5)", "numpy (>=1.22)", "pydata-sphinx-theme (>=0.13.3)", "sphinx (>=7)"] -test = ["matplotlib", "pytest", "pytest-cov"] - [[package]] name = "nvidia-cublas-cu12" version = "12.6.4.1" @@ -3639,6 +3634,19 @@ pygments = ">=2.13.0,<3.0.0" [package.extras] jupyter = ["ipywidgets (>=7.5.1,<9)"] +[[package]] +name = "roman-numerals" +version = "4.1.0" +description = "Manipulate well-formed Roman numerals" +optional = false +python-versions = ">=3.10" +groups = ["docs"] +markers = "python_version >= \"3.11\"" +files = [ + {file = "roman_numerals-4.1.0-py3-none-any.whl", hash = "sha256:647ba99caddc2cc1e55a51e4360689115551bf4476d90e8162cf8c345fe233c7"}, + {file = "roman_numerals-4.1.0.tar.gz", hash = "sha256:1af8b147eb1405d5839e78aeb93131690495fe9da5c91856cb33ad55a7f1e5b2"}, +] + [[package]] name = "rpds-py" version = "0.30.0" @@ -4055,6 +4063,7 @@ description = "Python documentation generator" optional = false python-versions = ">=3.8" groups = ["docs"] +markers = "python_version == \"3.10\"" files = [ {file = "Sphinx-6.2.1.tar.gz", hash = "sha256:6d56a34697bb749ffa0152feafc4b19836c755d90a7c59b72bc7dfd371b9cc6b"}, {file = "sphinx-6.2.1-py3-none-any.whl", hash = "sha256:97787ff1fa3256a3eef9eda523a63dbf299f7b47e053cfcf684a1c2a8380c912"}, @@ -4084,64 +4093,84 @@ lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-simplify", "isort", "mypy test = ["cython", "filelock", "html5lib", "pytest (>=4.6)"] [[package]] -name = "sphinx-autodoc-typehints" -version = "1.23.0" -description = "Type hints (PEP 484) support for the Sphinx autodoc extension" +name = "sphinx" +version = "9.0.4" +description = "Python documentation generator" optional = false -python-versions = ">=3.7" +python-versions = ">=3.11" groups = ["docs"] +markers = "python_version == \"3.11\"" files = [ - {file = "sphinx_autodoc_typehints-1.23.0-py3-none-any.whl", hash = "sha256:ac099057e66b09e51b698058ba7dd76e57e1fe696cd91b54e121d3dad188f91d"}, - {file = "sphinx_autodoc_typehints-1.23.0.tar.gz", hash = "sha256:5d44e2996633cdada499b6d27a496ddf9dbc95dd1f0f09f7b37940249e61f6e9"}, + {file = "sphinx-9.0.4-py3-none-any.whl", hash = "sha256:5bebc595a5e943ea248b99c13814c1c5e10b3ece718976824ffa7959ff95fffb"}, + {file = "sphinx-9.0.4.tar.gz", hash = "sha256:594ef59d042972abbc581d8baa577404abe4e6c3b04ef61bd7fc2acbd51f3fa3"}, ] [package.dependencies] -sphinx = ">=5.3" - -[package.extras] -docs = ["furo (>=2022.12.7)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.23.4)"] -testing = ["covdefaults (>=2.2.2)", "coverage (>=7.2.2)", "diff-cover (>=7.5)", "nptyping (>=2.5)", "pytest (>=7.2.2)", "pytest-cov (>=4)", "sphobjinv (>=2.3.1)", "typing-extensions (>=4.5)"] -type-comment = ["typed-ast (>=1.5.4) ; python_version < \"3.8\""] +alabaster = ">=0.7.14" +babel = ">=2.13" +colorama = {version = ">=0.4.6", markers = "sys_platform == \"win32\""} +docutils = ">=0.20,<0.23" +imagesize = ">=1.3" +Jinja2 = ">=3.1" +packaging = ">=23.0" +Pygments = ">=2.17" +requests = ">=2.30.0" +roman-numerals = ">=1.0.0" +snowballstemmer = ">=2.2" +sphinxcontrib-applehelp = ">=1.0.7" +sphinxcontrib-devhelp = ">=1.0.6" +sphinxcontrib-htmlhelp = ">=2.0.6" +sphinxcontrib-jsmath = ">=1.0.1" +sphinxcontrib-qthelp = ">=1.0.6" +sphinxcontrib-serializinghtml = ">=1.1.9" [[package]] -name = "sphinx-book-theme" -version = "1.1.2" -description = "A clean book theme for scientific explanations and documentation with Sphinx" +name = "sphinx" +version = "9.1.0" +description = "Python documentation generator" optional = false -python-versions = ">=3.9" +python-versions = ">=3.12" groups = ["docs"] +markers = "python_version >= \"3.12\"" files = [ - {file = "sphinx_book_theme-1.1.2-py3-none-any.whl", hash = "sha256:cee744466fde48f50302b851291b208aa67e726ca31b7a3bfb9b6e6a145663e0"}, - {file = "sphinx_book_theme-1.1.2.tar.gz", hash = "sha256:7f3abcd146ca82e6f39d6db53711102b1c1d328d12f65e3e47ad9bf842614a49"}, + {file = "sphinx-9.1.0-py3-none-any.whl", hash = "sha256:c84fdd4e782504495fe4f2c0b3413d6c2bf388589bb352d439b2a3bb99991978"}, + {file = "sphinx-9.1.0.tar.gz", hash = "sha256:7741722357dd75f8190766926071fed3bdc211c74dd2d7d4df5404da95930ddb"}, ] [package.dependencies] -pydata-sphinx-theme = ">=0.14" -sphinx = ">=5" - -[package.extras] -code-style = ["pre-commit"] -doc = ["ablog", "folium", "ipywidgets", "matplotlib", "myst-nb", "nbclient", "numpy", "numpydoc", "pandas", "plotly", "sphinx-copybutton", "sphinx-design", "sphinx-examples", "sphinx-tabs", "sphinx-thebe", "sphinx-togglebutton", "sphinxcontrib-bibtex", "sphinxcontrib-youtube", "sphinxext-opengraph"] -test = ["beautifulsoup4", "coverage", "myst-nb", "pytest", "pytest-cov", "pytest-regressions", "sphinx_thebe"] +alabaster = ">=0.7.14" +babel = ">=2.13" +colorama = {version = ">=0.4.6", markers = "sys_platform == \"win32\""} +docutils = ">=0.21,<0.23" +imagesize = ">=1.3" +Jinja2 = ">=3.1" +packaging = ">=23.0" +Pygments = ">=2.17" +requests = ">=2.30.0" +roman-numerals = ">=1.0.0" +snowballstemmer = ">=2.2" +sphinxcontrib-applehelp = ">=1.0.7" +sphinxcontrib-devhelp = ">=1.0.6" +sphinxcontrib-htmlhelp = ">=2.0.6" +sphinxcontrib-jsmath = ">=1.0.1" +sphinxcontrib-qthelp = ">=1.0.6" +sphinxcontrib-serializinghtml = ">=1.1.9" [[package]] -name = "sphinx-copybutton" -version = "0.5.2" -description = "Add a copy button to each of your code cells." +name = "sphinx-autodoc-typehints" +version = "3.10.2" +description = "Type hints (PEP 484) support for the Sphinx autodoc extension" optional = false -python-versions = ">=3.7" +python-versions = ">=3.12" groups = ["docs"] +markers = "python_version >= \"3.12\"" files = [ - {file = "sphinx-copybutton-0.5.2.tar.gz", hash = "sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd"}, - {file = "sphinx_copybutton-0.5.2-py3-none-any.whl", hash = "sha256:fb543fd386d917746c9a2c50360c7905b605726b9355cd26e9974857afeae06e"}, + {file = "sphinx_autodoc_typehints-3.10.2-py3-none-any.whl", hash = "sha256:2d1bcac8f62b8d0d210f6ca44b8e016e314d07cc8c30d0512cf6986a0b042b26"}, + {file = "sphinx_autodoc_typehints-3.10.2.tar.gz", hash = "sha256:34db651eb14343ba16bd9c03e0f5093971f9bbd3cc6b0a1470adecd578940b9c"}, ] [package.dependencies] -sphinx = ">=1.8" - -[package.extras] -code-style = ["pre-commit (==2.12.1)"] -rtd = ["ipython", "myst-nb", "sphinx", "sphinx-book-theme", "sphinx-examples"] +sphinx = ">=9.1" [[package]] name = "sphinx-design" @@ -4150,6 +4179,7 @@ description = "A sphinx extension for designing beautiful, view size responsive optional = false python-versions = ">=3.9" groups = ["docs"] +markers = "python_version == \"3.10\"" files = [ {file = "sphinx_design-0.6.1-py3-none-any.whl", hash = "sha256:b11f37db1a802a183d61b159d9a202314d4d2fe29c163437001324fe2f19549c"}, {file = "sphinx_design-0.6.1.tar.gz", hash = "sha256:b44eea3719386d04d765c1a8257caca2b3e6f8421d7b3a5e742c0fd45f84e632"}, @@ -4170,24 +4200,31 @@ theme-rtd = ["sphinx-rtd-theme (>=2.0,<3.0)"] theme-sbt = ["sphinx-book-theme (>=1.1,<2.0)"] [[package]] -name = "sphinx-rtd-theme" -version = "2.0.0" -description = "Read the Docs theme for Sphinx" +name = "sphinx-design" +version = "0.7.0" +description = "A sphinx extension for designing beautiful, view size responsive web components." optional = false -python-versions = ">=3.6" +python-versions = ">=3.11" groups = ["docs"] +markers = "python_version >= \"3.11\"" files = [ - {file = "sphinx_rtd_theme-2.0.0-py2.py3-none-any.whl", hash = "sha256:ec93d0856dc280cf3aee9a4c9807c60e027c7f7b461b77aeffed682e68f0e586"}, - {file = "sphinx_rtd_theme-2.0.0.tar.gz", hash = "sha256:bd5d7b80622406762073a04ef8fadc5f9151261563d47027de09910ce03afe6b"}, + {file = "sphinx_design-0.7.0-py3-none-any.whl", hash = "sha256:f82bf179951d58f55dca78ab3706aeafa496b741a91b1911d371441127d64282"}, + {file = "sphinx_design-0.7.0.tar.gz", hash = "sha256:d2a3f5b19c24b916adb52f97c5f00efab4009ca337812001109084a740ec9b7a"}, ] [package.dependencies] -docutils = "<0.21" -sphinx = ">=5,<8" -sphinxcontrib-jquery = ">=4,<5" +sphinx = ">=7,<10" [package.extras] -dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client", "wheel"] +code-style = ["pre-commit (>=3,<4)"] +rtd = ["myst-parser (>=4,<6)"] +testing = ["defusedxml", "myst-parser (>=4,<6)", "pytest (>=8.3,<9.0)", "pytest-cov", "pytest-regressions"] +testing-no-myst = ["defusedxml", "pytest (>=8.3,<9.0)", "pytest-cov", "pytest-regressions"] +theme-furo = ["furo (>=2024.7.18,<2024.8.0)"] +theme-im = ["sphinx-immaterial (>=0.12.2,<0.13.0)"] +theme-pydata = ["pydata-sphinx-theme (>=0.15.2,<0.16.0)"] +theme-rtd = ["sphinx-rtd-theme (>=2.0,<3.0)"] +theme-sbt = ["sphinx-book-theme (>=1.1,<2.0)"] [[package]] name = "sphinx-togglebutton" @@ -4210,6 +4247,23 @@ wheel = "*" [package.extras] sphinx = ["matplotlib", "myst-nb", "numpy", "sphinx-book-theme", "sphinx-design", "sphinx-examples"] +[[package]] +name = "sphinxawesome-theme" +version = "6.0.2" +description = "An awesome theme for the Sphinx documentation generator" +optional = false +python-versions = ">=3.10" +groups = ["docs"] +markers = "python_version >= \"3.12\"" +files = [ + {file = "sphinxawesome_theme-6.0.2-py3-none-any.whl", hash = "sha256:a35dcabe3b0906aff270e1d18948f93040769e76551a2eb26cf26b29e06d1e51"}, + {file = "sphinxawesome_theme-6.0.2.tar.gz", hash = "sha256:984c1a107584eb6a913ba4c2e4c74b23212fbffeee9ef60688810b46823ade25"}, +] + +[package.dependencies] +beautifulsoup4 = ">=4.9.1,<5" +sphinx = ">7,<10" + [[package]] name = "sphinxcontrib-applehelp" version = "2.0.0" @@ -4261,21 +4315,6 @@ lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] standalone = ["Sphinx (>=5)"] test = ["html5lib", "pytest"] -[[package]] -name = "sphinxcontrib-jquery" -version = "4.1" -description = "Extension to include jQuery on newer Sphinx releases" -optional = false -python-versions = ">=2.7" -groups = ["docs"] -files = [ - {file = "sphinxcontrib-jquery-4.1.tar.gz", hash = "sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a"}, - {file = "sphinxcontrib_jquery-4.1-py2.py3-none-any.whl", hash = "sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae"}, -] - -[package.dependencies] -Sphinx = ">=1.8" - [[package]] name = "sphinxcontrib-jsmath" version = "1.0.1" @@ -4383,21 +4422,6 @@ mpmath = ">=1.1.0,<1.4" [package.extras] dev = ["hypothesis (>=6.70.0)", "pytest (>=7.1.0)"] -[[package]] -name = "tabulate" -version = "0.10.0" -description = "Pretty-print tabular data" -optional = false -python-versions = ">=3.10" -groups = ["docs"] -files = [ - {file = "tabulate-0.10.0-py3-none-any.whl", hash = "sha256:f0b0622e567335c8fabaaa659f1b33bcb6ddfe2e496071b743aa113f8774f2d3"}, - {file = "tabulate-0.10.0.tar.gz", hash = "sha256:e2cfde8f79420f6deeffdeda9aaec3b6bc5abce947655d17ac662b126e48a60d"}, -] - -[package.extras] -widechars = ["wcwidth"] - [[package]] name = "termcolor" version = "2.5.0" @@ -4933,4 +4957,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<3.14" -content-hash = "cd3e8982de0d6cb28767f7bfe3aef250c1254eff982f84a740633aa319bb09b0" +content-hash = "4350cd94abb108d441d97e017e3a74f54308ff93e6fadeadd8514f9b7cb690ef" diff --git a/pyproject.toml b/pyproject.toml index a611280..b8c3734 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,17 +43,15 @@ pyright = "^1.1.409" [tool.poetry.group.docs.dependencies] setuptools = "*" -sphinx = "6.2.1" -sphinx-autodoc-typehints = "1.23.0" -numpydoc = "1.7.0" +sphinx = { version = "9.1.0", python = ">=3.12" } +sphinx-autodoc-typehints = { version = ">=3.0", python = ">=3.12" } +numpydoc = ">=1.8" nbsphinx = "0.9.4" ipython = "*" -myst-parser = "3.0.1" -m2r2 = "0.3.3.post2" -sphinx-copybutton = "0.5.2" +myst-parser = { version = ">=4.0", python = ">=3.12" } + sphinx-togglebutton = "0.3.2" -sphinx-book-theme = "1.1.2" -sphinx-rtd-theme = "2.0.0" +sphinxawesome-theme = { version = ">=6.0", python = ">=3.12" } readthedocs-sphinx-ext = "2.2.5" lxml-html-clean = "0.4.0" pydata-sphinx-theme = "0.15.2" diff --git a/readthedocs.yaml b/readthedocs.yaml index 38e2867..e4b3d29 100644 --- a/readthedocs.yaml +++ b/readthedocs.yaml @@ -7,9 +7,9 @@ version: 2 # Set the OS, Python version and other tools you might need build: - os: ubuntu-22.04 + os: ubuntu-24.04 tools: - python: "3.10" + python: "3.12" # You can also specify other tool versions: # nodejs: "19" # rust: "1.64" From 8ad823aff251e40e52e49dd64672f469cb7cd2f5 Mon Sep 17 00:00:00 2001 From: Manish Kumar Date: Sun, 17 May 2026 00:29:56 +0200 Subject: [PATCH 2/7] docs: deduplicate contributing.md and release.md; add cross-references --- docs/developer_guide/contributing.md | 222 +++++---------------------- docs/developer_guide/release.md | 21 +-- 2 files changed, 43 insertions(+), 200 deletions(-) diff --git a/docs/developer_guide/contributing.md b/docs/developer_guide/contributing.md index 6e564b3..a69be65 100644 --- a/docs/developer_guide/contributing.md +++ b/docs/developer_guide/contributing.md @@ -69,28 +69,37 @@ pip install -r docs/requirements_docs.txt 2. Make your desired changes or additions to the codebase. 3. Ensure that your code adheres to [PEP8](https://peps.python.org/pep-0008/) coding style guidelines. 4. Write appropriate tests for your changes and verify they pass: - ```bash - just test - ``` + +```bash +just test +``` + 5. Update the documentation and examples, if necessary. 6. Build the HTML documentation and verify it works as expected: - ```bash - just docs - ``` - Verify the output under `docs/_build/html/`. `index.html` is the entry point. -7. Run the full local check suite before pushing (lint, format, type-check, and all pre-commit hooks): - ```bash - just check - ``` - If `ruff-format` modifies any files, commit those changes before pushing: - ```bash - git add -u - git commit -m "style: apply ruff formatting" - ``` + +```bash +just docs +``` + +Verify the output under `docs/_build/html/`. `index.html` is the entry point. 7. Run the full local check suite before pushing (lint, format, type-check, and all pre-commit hooks): + +```bash +just check +``` + +If `ruff-format` modifies any files, commit those changes before pushing: + +```bash +git add -u +git commit -m "style: apply ruff formatting" +``` + 8. Commit your changes following the Conventional Commits specification (see below): - ```bash - just commit - ``` + +```bash +just commit +``` + 9. Submit a pull request from your branch to `main` in the original repository. 10. Wait for the maintainers to review your pull request. Address any feedback or comments if required. 11. Once approved, your changes will be merged into the main codebase. @@ -134,181 +143,24 @@ just typecheck Fix any reported errors before opening a PR. -## Docs Workflow - -Documentation is built with [Sphinx](https://www.sphinx-doc.org/) and hosted on [Read the Docs](https://readthedocs.org/). - -The docs CI is defined in `.github/workflows/docs.yml` and is separate from the main CI workflow. - -### How docs are published - -| Trigger | CI (`docs.yml`) | Read the Docs | -| --------------------------------------------------------------------- | ----------------------------------------------------- | ------------------------------------------------------------- | -| PR touching `docs/**`, `deeptab/**`, `README.md`, or `pyproject.toml` | Sphinx build check — PR is blocked if docs are broken | No publish | -| Merge to `main` | Sphinx build check | Publishes **latest** (dev) version | -| Stable tag pushed (`vX.Y.Z`) | Sphinx build check from that exact tagged commit | Publishes **versioned** snapshot and updates **stable** alias | -| RC tag pushed (`vX.Y.Zrc1`) | Sphinx build check from that exact tagged commit | Publishes versioned pre-release snapshot | - -> **Note:** The docs CI `push` trigger has **no `paths:` filter** — tag pushes always run the full docs build regardless of which files changed in the tagged commit. The `paths:` filter only applies to PRs to keep checks fast. - -> **Note:** Versioned and stable docs require **"Build tags"** to be enabled in the Read the Docs project settings under _Admin → Advanced settings_. RTD automatically sets the `stable` alias to the highest non-pre-release tag. - -### Tag → versioned docs flow +## Documentation -``` -git tag -a v1.7.0 -m "Release v1.7.0" -git push origin v1.7.0 - ↓ -docs.yml triggers on that exact tagged commit - ↓ -Sphinx build succeeds (or blocks if broken) - ↓ -RTD webhook fires → builds docs from v1.7.0 source - ↓ -RTD publishes /en/v1.7.0/ (versioned) - ↓ -RTD updates /en/stable/ → points to v1.7.0 -``` - -RC tags (`vX.Y.Zrc1`) follow the same flow but RTD does **not** update the `stable` alias for pre-release tags. +For a full description of the Sphinx setup, how to add pages, write docstrings, and how the ReadTheDocs deployment works, see the dedicated **[Documentation](documentation.md)** page. -### Building docs locally +Quick reference: ```bash -# Install system dependency (macOS) -brew install pandoc -# or on Ubuntu -sudo apt-get install pandoc - -# Install doc dependencies (if not already done) -poetry install --with docs - -# Build HTML docs (warnings treated as errors) -sphinx-build -b html docs/ docs/_build/html -W --keep-going - -# Open in browser +just docs # build HTML locally open docs/_build/html/index.html ``` -### Version resolution - -The docs version is read at build time from the installed package metadata via `importlib.metadata.version("deeptab")`, which reflects the version in `pyproject.toml`. No separate version file is maintained. - -## Release Workflow - -This project uses conventional commits and intentional, maintainer-controlled releases. - -### Release Process Overview - -``` -1. Make Changes → 2. Conventional Commit → 3. Merge to Main → 4. CI runs - ↓ - (no automatic release — main is not a release trigger) - -5. Maintainer opens Release PR → version bump + CHANGELOG update → merge to main -6. Maintainer creates Git tag → PyPI publish triggered automatically -``` - -**Step-by-Step:** - -1. **Development Phase** - - Create feature branch from `main` - - Make your changes - - Commit using conventional commits (e.g., `feat:`, `fix:`) - -2. **Merge to Main** (CI only — no release) - - Create PR to `main` - - After review, merge to `main` - - GitHub Actions runs tests - - **No version bump, no tag, no PyPI publish happens automatically** - -3. **Maintainer Release PR** (periodic, intentional) - - Maintainer creates a `release/vX.Y.Z` branch - - Runs `cz bump` to update `pyproject.toml` and `CHANGELOG.md` - - Opens PR to `main`, merges after review - -4. **Maintainer Creates Git Tag** - - After the release PR is merged: - ```bash - git checkout main && git pull - git tag -a vX.Y.Z -m "Release vX.Y.Z" - git push origin vX.Y.Z - ``` - - This tag push triggers `publish-pypi.yml` → builds and publishes to PyPI + creates GitHub Release - - For RC tags (`vX.Y.Zrc1`), push triggers `publish-testpypi.yml` → publishes to TestPyPI, then a second `smoke-test-testpypi` job installs the exact RC from TestPyPI in a clean environment and runs an import smoke test to confirm the uploaded package is installable from the index - -### Validating a Build Without Publishing - -Before cutting a tag or publishing anywhere, you can trigger a full dry-run build via the **Build & Check** workflow: - -1. Go to **Actions → Build & Check (dry run)** in the GitHub repository. -2. Click **Run workflow** and select the branch to validate. -3. The workflow will: - - Build both wheel and sdist with Poetry - - Run `twine check` on both artifacts - - Install the wheel in a fresh virtual environment and run an import smoke test - - Upload the `dist/` folder as a downloadable artifact (retained for 7 days) - -This is the recommended step before opening a release PR or pushing an RC tag. - -### What Triggers a Release? - -| Event | Result | -| ----------------------------- | ------------------------------------------------------------------- | -| `workflow_dispatch` | Dry-run build + twine check + smoke test (no publish) | -| Push to `main` | CI tests only | -| Maintainer pushes `v*rc*` tag | TestPyPI publish + GitHub pre-release + TestPyPI install smoke test | -| Maintainer pushes `v*` tag | PyPI publish + GitHub Release | - -### Commit Types and Their Effect on Version - -Commit messages determine the version bump chosen by the maintainer when running `cz bump`: - -| Commit Type | Version Bump | -| -------------------------------------------------------- | ----------------- | -| `feat:` | Minor (1.x.0) | -| `fix:`, `perf:` | Patch (1.6.x) | -| `feat!:` / `BREAKING CHANGE:` | Major (x.0.0) | -| `docs:`, `style:`, `refactor:`, `test:`, `chore:`, `ci:` | No release needed | - -### Example Scenarios - -**Scenario 1: Documentation Update (No Release)** - -```bash -git commit -m "docs: update API reference" -# Merge to main → CI only, no release -``` - -**Scenario 2: Bug Fix (Patch Release)** - -```bash -git commit -m "fix: resolve memory leak in dataloader" -# Merged to main → later, maintainer runs cz bump → creates v1.6.2 tag → PyPI release -``` - -**Scenario 3: New Feature (Minor Release)** - -```bash -git commit -m "feat(models): add TabNet architecture" -# Merged to main → later, maintainer runs cz bump → creates v1.7.0 tag → PyPI release -``` - -**Scenario 4: RC for risky feature** - -```bash -# Maintainer tags manually: -git tag -a v1.7.0rc1 -m "Release candidate v1.7.0rc1" -git push origin v1.7.0rc1 -# → PyPI pre-release, GitHub pre-release -``` +## Release workflow -### Important Notes +For the end-to-end release procedure (version bump, tags, PyPI publishing) see: -- **Merging to `main` never triggers a PyPI release** -- **Only a manually pushed `v*` tag triggers publishing** -- **Never manually edit the version number** in `pyproject.toml` — use `cz bump` on a release branch -- **PyPI publishing** uses OIDC Trusted Publishing — no API tokens are stored in GitHub secrets +- **[Release process](release.md)** — step-by-step instructions +- **[Versioning](versioning.md)** — SemVer rules, commit types, `cz bump` +- **[CI/CD](ci_cd.md)** — what each GitHub Actions workflow does ## Submitting Contributions diff --git a/docs/developer_guide/release.md b/docs/developer_guide/release.md index 0348641..7ccbc92 100644 --- a/docs/developer_guide/release.md +++ b/docs/developer_guide/release.md @@ -58,9 +58,7 @@ Fix any docstring related issue, then proceed with next steps. ## 2. Version update -The package version is maintained in `pyproject.toml` only. The version is read at runtime via `importlib.metadata`. - -On a `release/vX.Y.Z` branch: +See **[Versioning](versioning.md)** for the full explanation of SemVer rules, commit types, and how `cz bump` works. The commands are summarised below. **For a stable release** — let `cz bump` derive the next version automatically from conventional commits: @@ -123,21 +121,14 @@ git tag -a vX.Y.Z -m "Release vX.Y.Z" git push origin vX.Y.Z ``` -## 6. Publish package to PyPI - -The tag push automatically triggers the appropriate workflow in GitHub Actions: - -- Stable tag (`vX.Y.Z`) → `publish-pypi.yml` → publishes to **PyPI** + creates GitHub Release -- RC tag (`vX.Y.ZrcN`) → `publish-testpypi.yml` → publishes to **TestPyPI** + creates GitHub pre-release +## 6. Publish package -Both workflows: +The tag push automatically triggers the appropriate GitHub Actions workflow — see **[CI/CD](ci_cd.md)** for the full workflow details. In summary: -- Build the package (`poetry build`) -- Validate with `twine check` -- Publish via **OIDC Trusted Publishing** (no API tokens required) -- Create a GitHub Release with auto-generated notes +- Stable tag (`vX.Y.Z`) → `publish-pypi.yml` → PyPI + GitHub Release +- RC tag (`vX.Y.ZrcN`) → `publish-testpypi.yml` → TestPyPI + GitHub pre-release -> **Note:** A `pypi-publish` GitHub Environment (for stable) and `testpypi-publish` environment (for RCs) must be configured with tag-based deployment protection rules. +Both workflows use **OIDC Trusted Publishing** (no API tokens required). ## 7. GitHub Release From c084f25b749e1ab165178a31f76aa5ab76429522 Mon Sep 17 00:00:00 2001 From: Manish Kumar Date: Sun, 17 May 2026 00:30:33 +0200 Subject: [PATCH 3/7] docs: add developer guide pages for testing, documentation, versioning, CI/CD --- docs/developer_guide/ci_cd.md | 124 ++++++++++++++++++++++++++ docs/developer_guide/documentation.md | 116 ++++++++++++++++++++++++ docs/developer_guide/testing.md | 87 ++++++++++++++++++ docs/developer_guide/versioning.md | 93 +++++++++++++++++++ docs/index.rst | 7 +- 5 files changed, 426 insertions(+), 1 deletion(-) create mode 100644 docs/developer_guide/ci_cd.md create mode 100644 docs/developer_guide/documentation.md create mode 100644 docs/developer_guide/testing.md create mode 100644 docs/developer_guide/versioning.md diff --git a/docs/developer_guide/ci_cd.md b/docs/developer_guide/ci_cd.md new file mode 100644 index 0000000..dbb905e --- /dev/null +++ b/docs/developer_guide/ci_cd.md @@ -0,0 +1,124 @@ +# CI/CD + +DeepTab uses GitHub Actions for continuous integration and delivery. All workflows live in `.github/workflows/`. + +## Workflow overview + +| Workflow file | Trigger | Purpose | +| ---------------------- | ---------------------------- | ---------------------------------------- | +| `ci.yml` | Push / PR → `main` | Lint, type-check, build, and test | +| `docs.yml` | Push / PR (docs paths), tags | Build Sphinx docs; deploy to ReadTheDocs | +| `build-check.yml` | Manual (`workflow_dispatch`) | Dry-run build validation before tagging | +| `publish-testpypi.yml` | Push of `vX.Y.ZrcN` tag | Publish release candidate to TestPyPI | +| `publish-pypi.yml` | Push of `vX.Y.Z` stable tag | Publish stable release to PyPI | + +--- + +## ci.yml — Continuous integration + +Runs on every push to `main` and every pull request targeting `main`. Cancels in-progress runs for the same branch via `concurrency`. + +### Jobs + +**`lint`** — runs on `ubuntu-latest` / Python 3.10: + +```bash +ruff check . # style and correctness +ruff format --check . # formatting (no changes applied) +``` + +**`typecheck`** — runs on `ubuntu-latest` / Python 3.10: + +```bash +pyright +``` + +**`build`** — runs on `ubuntu-latest` / Python 3.10: + +```bash +poetry build +twine check dist/* +``` + +**`tests`** — runs across a full matrix: + +| Dimension | Values | +| --------- | ------------------------------------------------- | +| OS | `ubuntu-latest`, `macos-latest`, `windows-latest` | +| Python | `3.10`, `3.11`, `3.12`, `3.13` | + +```bash +pytest tests/ -v +``` + +All jobs are independent; `fail-fast: false` ensures a failure in one matrix cell does not cancel the others. + +--- + +## docs.yml — Documentation build + +Runs on: + +- Every push to `main` (always, regardless of changed paths — needed so tag pushes rebuild docs). +- Pull requests that touch `docs/**`, `README.md`, `pyproject.toml`, or `deeptab/**`. +- Every version tag (`v*`). + +The job installs `pandoc`, installs the `docs` dependency group via Poetry, then runs: + +```bash +poetry run sphinx-build -b html docs/ docs/_build/html -W --keep-going +``` + +On `main` pushes, the built HTML is deployed to ReadTheDocs automatically via the RTD webhook configured in `readthedocs.yaml`. + +--- + +## build-check.yml — Manual dry-run + +A `workflow_dispatch`-only workflow. Builds the package with Poetry and validates it with `twine check` without publishing anywhere. Use it to validate a release candidate before tagging: + +1. Navigate to **Actions → Build & Check (dry run)** in the GitHub UI. +2. Click **Run workflow** and select the release branch. +3. Confirm `twine check dist/*` passes before cutting the tag. + +--- + +## publish-testpypi.yml — Release candidate publishing + +Triggered by any tag matching `v*.*.*rc*`. Uses [OIDC trusted publishing](https://docs.pypi.org/trusted-publishers/) — no `PYPI_TOKEN` secret is required. + +Steps: + +1. Build the package with `poetry build`. +2. Publish to [TestPyPI](https://test.pypi.org/project/deeptab/). +3. Create a GitHub pre-release via `gh release create`. + +The `pypi-publish` GitHub Environment is required; it must have the `v*rc*` tag pattern in its protection rules. + +--- + +## publish-pypi.yml — Stable release publishing + +Triggered by any tag matching `v*.*.*` that does **not** contain `rc` (stable only). Also uses OIDC trusted publishing. + +Steps: + +1. Build the package with `poetry build`. +2. Publish to [PyPI](https://pypi.org/project/deeptab/). +3. Create a GitHub release with auto-generated release notes. + +See the [Release process](release.md) page for the full end-to-end procedure including when and how to push these tags. + +--- + +## Adding or modifying a workflow + +1. Edit the relevant YAML file in `.github/workflows/`. +2. Use [act](https://github.com/nektos/act) to test locally before pushing: + +```bash +act push --job tests +``` + +3. Keep job names consistent — they are displayed in PR status checks and on the Actions tab. +4. Pin third-party actions to a full commit SHA or a tagged version (e.g. `actions/checkout@v4`) and keep them up to date via `just update` (which runs `pre-commit autoupdate`). diff --git a/docs/developer_guide/documentation.md b/docs/developer_guide/documentation.md new file mode 100644 index 0000000..2ec072f --- /dev/null +++ b/docs/developer_guide/documentation.md @@ -0,0 +1,116 @@ +# Documentation + +DeepTab documentation is built with [Sphinx 9](https://www.sphinx-doc.org/) using the [sphinxawesome-theme](https://sphinxawesome.xyz/). Pages are written in [MyST Markdown](https://myst-parser.readthedocs.io/) or reStructuredText. API reference pages are generated automatically from docstrings via [autodoc](https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html) and [numpydoc](https://numpydoc.readthedocs.io/). + +## Building locally + +```bash +just docs +``` + +This runs: + +```bash +poetry run sphinx-build -b html docs/ docs/_build/html -W --keep-going +``` + +The `-W` flag treats every Sphinx warning as a build error; `-keep-going` collects all warnings before stopping so you can fix them in one pass. Open `docs/_build/html/index.html` in a browser to preview the result. + +## Directory layout + +``` +docs/ +├── conf.py # Sphinx configuration +├── index.rst # Root toctree (navigation structure) +├── _static/ +│ └── custom.css # Theme overrides and syntax highlight palette +├── homepage.md # Landing page content +├── overview.md +├── installation.md +├── key_concepts.md +├── examples/ # Tutorial pages +├── api/ # Auto-generated API reference +└── developer_guide/ # This section +``` + +## Adding a new page + +1. Create a `.md` file in the appropriate sub-directory (e.g. `docs/developer_guide/my_topic.md`). +2. Add the path (without extension) to the matching `.. toctree::` block in `docs/index.rst`: + +```rst +.. toctree:: + :caption: Developer Guide + :maxdepth: 1 + :hidden: + + developer_guide/my_topic +``` + +3. Run `just docs` and fix any warnings before opening a PR. + +## Docstring style + +All public classes and functions use **NumPy-style docstrings**. The full specification is at [numpydoc.readthedocs.io](https://numpydoc.readthedocs.io/en/latest/format.html). A minimal example: + +```python +def fit(self, X, y, val_size=0.2): + """Fit the model to training data. + + Parameters + ---------- + X : array-like of shape (n_samples, n_features) + Training feature matrix. + y : array-like of shape (n_samples,) + Target values. + val_size : float, default=0.2 + Fraction of training data used for validation. + + Returns + ------- + self : object + Fitted estimator. + + Raises + ------ + ValueError + If ``X`` and ``y`` have incompatible shapes. + """ +``` + +## Preventing duplicate-description warnings + +Sphinx raises a warning when `autodoc` documents the same symbol more than once. If a class is re-exported from a package `__init__`, add `:noindex:` to the second occurrence's directive: + +```rst +.. autoclass:: deeptab.models.TabNet + :noindex: +``` + +## Code blocks in pages + +Use fenced code blocks with a language tag for syntax highlighting: + +````markdown +```python +model = TabNet() +model.fit(X_train, y_train) +``` +```` + +For shell commands use ` ```bash ` or ` ```sh `. + +## Mermaid diagrams + +The `sphinxcontrib-mermaid` extension is enabled. Use a `mermaid` code fence: + +````markdown +```{mermaid} +flowchart LR + A[Start] --> B[End] +``` +```` + +## ReadTheDocs + +Documentation is hosted on ReadTheDocs and built automatically on every push to `main` and on every new release tag. The build configuration lives in `readthedocs.yaml` at the repository root. RTD uses Python 3.12 on Ubuntu 24.04. diff --git a/docs/developer_guide/testing.md b/docs/developer_guide/testing.md new file mode 100644 index 0000000..19bc425 --- /dev/null +++ b/docs/developer_guide/testing.md @@ -0,0 +1,87 @@ +# Testing + +DeepTab uses [pytest](https://docs.pytest.org/) with [pytest-cov](https://pytest-cov.readthedocs.io/) for test coverage. The test suite runs against all supported Python versions and operating systems on every push and pull request. + +## Running the test suite + +```bash +just test +``` + +This expands to: + +```bash +poetry run pytest --cov=deeptab tests/ +``` + +To run a single file or a specific test: + +```bash +poetry run pytest tests/test_models.py -v +poetry run pytest tests/test_models.py::test_tabnet_fit -v +``` + +To print live log output and stop on the first failure: + +```bash +poetry run pytest tests/ -x -s +``` + +## Test files + +| File | What it covers | +| ----------------------------- | --------------------------------------------------------------------- | +| `tests/test_models.py` | End-to-end fit/predict cycle for every model | +| `tests/test_base.py` | Shared base-class behaviour (sklearn API, `set_params`, `get_params`) | +| `tests/test_configs.py` | Config dataclass validation and default values | +| `tests/test_model_exports.py` | ONNX export and TorchScript tracing | +| `tests/test_save_load.py` | Checkpoint save / load round-trips | + +## Writing new tests + +- Place tests in `tests/` using the `test_*.py` naming convention. +- Prefer parametrize over copy-paste for variations of the same test: + +```python +import pytest + +@pytest.mark.parametrize("n_layers", [1, 2, 4]) +def test_depth(n_layers): + ... +``` + +- Use small synthetic datasets (`n=64`, `d=8`) to keep tests fast. Avoid downloading external data in tests. +- Models rely on PyTorch Lightning internally. To suppress verbose trainer output in tests, set: + +```python +import logging +logging.getLogger("lightning.pytorch").setLevel(logging.ERROR) +``` + +## Coverage + +A coverage report is printed to the terminal after every `just test` run. To generate an interactive HTML report: + +```bash +poetry run pytest --cov=deeptab --cov-report=html tests/ +open htmlcov/index.html +``` + +## CI test matrix + +The `ci.yml` workflow runs the full suite on every push to `main` and on every pull request, across: + +| Dimension | Values | +| ---------- | ------------------------------------------------- | +| **Python** | 3.10, 3.11, 3.12, 3.13 | +| **OS** | `ubuntu-latest`, `macos-latest`, `windows-latest` | + +All 12 combinations run in parallel with `fail-fast: false`, so a failure in one combination does not cancel the others. + +## Pre-push checks + +The pre-commit configuration includes a push-stage hook that runs the full test suite before `git push`. This is installed automatically by `just install`. To run it manually: + +```bash +just check +``` diff --git a/docs/developer_guide/versioning.md b/docs/developer_guide/versioning.md new file mode 100644 index 0000000..a6e6c1e --- /dev/null +++ b/docs/developer_guide/versioning.md @@ -0,0 +1,93 @@ +# Versioning + +DeepTab follows [Semantic Versioning 2.0](https://semver.org/) and uses [Conventional Commits](https://www.conventionalcommits.org/) to automate version bumps and changelog generation via [commitizen](https://commitizen-tools.github.io/commitizen/). + +## Version format + +``` +MAJOR.MINOR.PATCH +``` + +| Segment | When it increments | +| ------- | -------------------------------------------------------------------------- | +| `MAJOR` | Breaking change (`feat!:` or `BREAKING CHANGE:` footer) | +| `MINOR` | New backwards-compatible feature (`feat:`) | +| `PATCH` | Backwards-compatible bug fix (`fix:`) or performance improvement (`perf:`) | + +Release candidates use the suffix `rcN`, e.g. `1.8.0rc1`. + +The version is defined **in one place only** — `pyproject.toml` — and read at runtime via `importlib.metadata`: + +```python +from importlib.metadata import version +__version__ = version("deeptab") +``` + +## Commit types and their effect + +| Commit type | Example | Version bump | +| ----------- | ------------------------------------------- | ------------ | +| `feat` | `feat(models): add TabM architecture` | Minor | +| `fix` | `fix(datamodule): resolve NaN propagation` | Patch | +| `perf` | `perf(transformer): fuse attention kernels` | Patch | +| `feat!` | `feat!: remove Python 3.9 support` | Major | +| `docs` | `docs: update API reference` | None | +| `test` | `test: add save/load round-trip test` | None | +| `ci` | `ci: add Python 3.13 to matrix` | None | +| `refactor` | `refactor: simplify config validation` | None | +| `style` | `style: apply ruff formatting` | None | +| `chore` | `chore: update pre-commit revisions` | None | + +Commit messages that do not match any of these types do not trigger a version bump. + +## Making a conventional commit + +Use commitizen's interactive prompt rather than writing the message by hand: + +```bash +just commit # opens the cz commit wizard +``` + +Or write the message directly: + +```bash +git commit -m "feat(models): add NODE architecture" +git commit -m "fix(configs): validate n_layers > 0" +``` + +The `commit-msg` pre-commit hook validates every commit message against the conventional commits format and rejects non-conforming messages. + +## Bumping the version + +On a `release/vX.Y.Z` branch, let commitizen determine the next version automatically: + +```bash +cz bump +``` + +This command: + +1. Reads all conventional commits since the last tag. +2. Determines the next version (`MAJOR`, `MINOR`, or `PATCH`). +3. Updates `version` in `pyproject.toml`. +4. Appends the new section to `CHANGELOG.md`. +5. Creates a local commit `bump: version X.Y.Z-1 → X.Y.Z`. + +For a release candidate, set the version explicitly instead: + +```bash +poetry version 1.8.0rc1 +poetry lock +git add pyproject.toml poetry.lock CHANGELOG.md +git commit -m "bump: version 1.7.0 → 1.8.0rc1" +``` + +## Changelog + +`CHANGELOG.md` at the repository root is the authoritative changelog. It is updated automatically by `cz bump` on stable releases. For release candidates, update it manually before tagging. + +The changelog format groups changes under the commit types (`feat`, `fix`, `perf`, etc.) and lists the subject line of every matching commit since the previous release. + +## Tags + +All release tags follow the format `vMAJOR.MINOR.PATCH` (or `vMAJOR.MINOR.PATCHrcN` for RCs). Tags are what trigger the PyPI publish workflows — see the [Release process](release.md) page for the full end-to-end procedure. diff --git a/docs/index.rst b/docs/index.rst index 874df7c..8ffedab 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,7 +3,8 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -.. mdinclude:: homepage.md +.. include:: homepage.md + :parser: myst_parser.sphinx_ .. toctree:: :name: Getting Started @@ -45,6 +46,10 @@ :hidden: developer_guide/contributing + developer_guide/testing + developer_guide/documentation developer_guide/release + developer_guide/versioning + developer_guide/ci_cd developer_guide/model_promotion_policy developer_guide/support_matrix From f9c33b71618f9171295218d0f219d1ce0b572f2e Mon Sep 17 00:00:00 2001 From: Manish Kumar Date: Sun, 17 May 2026 00:30:58 +0200 Subject: [PATCH 4/7] docs: suppress toctree sidebar on API pages; keep models nav collapsed --- docs/_templates/sidebar_toc.html | 5 +++ docs/conf.py | 60 ++++++++++++++------------------ 2 files changed, 31 insertions(+), 34 deletions(-) create mode 100644 docs/_templates/sidebar_toc.html diff --git a/docs/_templates/sidebar_toc.html b/docs/_templates/sidebar_toc.html new file mode 100644 index 0000000..7d7cd19 --- /dev/null +++ b/docs/_templates/sidebar_toc.html @@ -0,0 +1,5 @@ + diff --git a/docs/conf.py b/docs/conf.py index 7a33ec6..49b0780 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -8,6 +8,8 @@ from importlib.metadata import PackageNotFoundError from importlib.metadata import version as _version +from sphinxawesome_theme.postprocess import Icons + # -- Project information ----------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information @@ -39,15 +41,12 @@ "sphinx.ext.coverage", "sphinx.ext.mathjax", "sphinx.ext.ifconfig", - "sphinx_copybutton", "sphinx_togglebutton", "nbsphinx", "numpydoc", "IPython.sphinxext.ipython_console_highlighting", "IPython.sphinxext.ipython_directive", "myst_parser", - "mdinclude", # custom module - "sphinx_rtd_theme", "sphinxcontrib.mermaid", # "pydata_sphinx_theme", "sphinx_autodoc_typehints", @@ -77,8 +76,8 @@ source_suffix = [".rst", ".md"] # source_suffix = ".rst" -# The master toctree document. -master_doc = "index" +# The root toctree document. +root_doc = "index" # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. @@ -107,38 +106,38 @@ # The name of the Pygments (syntax highlighting) style to use. pygments_style = "github-light" +pygments_style_dark = "github-dark" # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output -# 'sphinx_rtd_theme' # 'furo', 'press', 'pydata_sphinx_theme' -html_theme = "sphinx_book_theme" +# sphinxawesome_theme +html_theme = "sphinxawesome_theme" html_static_path = ["_static"] html_css_files = ["custom.css"] +templates_path = ["_templates"] html_extra_path = ["llms.txt"] html_theme_options = { - "repository_url": "https://github.com/OpenTabular/DeepTab", - "repository_branch": "main", - "path_to_docs": "docs", - "use_edit_page_button": False, - "use_source_button": False, - "show_toc_level": 2, - "navigation_with_keys": True, + "show_breadcrumbs": True, "show_prev_next": True, - "globaltoc_collapse": False, - "icon_links": [ - { - "name": "GitHub", - "url": "https://github.com/OpenTabular/DeepTab", - "icon": "fa-brands fa-github", - }, - { - "name": "PyPI", - "url": "https://pypi.org/project/deeptab/", - "icon": "fa-brands fa-python", - }, - ], + "show_scrolltop": True, + "awesome_headerlinks": True, + "awesome_external_links": True, + "main_nav_links": { + "GitHub": "https://github.com/OpenTabular/DeepTab", + "PyPI": "https://pypi.org/project/deeptab/", + }, +} + +# Use the theme's own permalink icon +html_permalinks_icon = Icons.permalinks_icon + +# On API reference pages the page TOC would list every class and every method — +# hundreds of entries. Suppress it there; keep it on regular doc pages. +html_sidebars = { + "api/**": ["sidebar_main_nav_links.html"], + "**": ["sidebar_main_nav_links.html", "sidebar_toc.html"], } # The name of an image file (relative to this directory) to place at the top @@ -150,13 +149,6 @@ # Format of the last updated section in the footer html_last_updated_fmt = "%Y-%m-%d" -html_context = { - "github_user": "OpenTabular", - "github_repo": "DeepTab", - "github_version": "main", - "doc_path": "docs", -} - # -- Options for autodoc ------------------------------------------------------ autodoc_default_options = { From aa6365feff763af7e7b5f916cfa432687476d816 Mon Sep 17 00:00:00 2001 From: Manish Kumar Date: Sun, 17 May 2026 00:31:29 +0200 Subject: [PATCH 5/7] docs: rewrite custom.css for sphinxawesome-theme (remove pydata selectors) --- docs/_static/custom.css | 288 +++++++++++++++++----------------------- 1 file changed, 123 insertions(+), 165 deletions(-) diff --git a/docs/_static/custom.css b/docs/_static/custom.css index a79ce13..a4fefa1 100644 --- a/docs/_static/custom.css +++ b/docs/_static/custom.css @@ -1,43 +1,91 @@ -@import url("https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&display=swap"); - -:root { - font-size: 95%; /* zoom-out: more content per page */ - --pst-color-primary: #2563eb; - --pst-color-secondary: #7c3aed; - --pst-color-accent: #06b6d4; - --pst-color-link: #2563eb; - --pst-font-size-base: 1rem; - --code-font: +/* + * custom.css — sphinxawesome_theme compatible + * + * NOTE: This file must NOT use --pst-color-* variables or .bd-* selectors. + * Those belong to pydata-sphinx-theme / sphinx-book-theme and do not exist + * here. All overrides use standard CSS selectors or sphinxawesome variables. + */ + +@import url("https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,400;0,500;1,400&display=swap"); + +/* ── Monospace font for all code ─────────────────────────────────────────── */ +code, +kbd, +samp, +pre, +.highlight pre, +tt.literal, +code.literal { + font-family: "JetBrains Mono", "Fira Code", "Cascadia Code", "SF Mono", "Consolas", monospace; } -html[data-theme="dark"] { - --pst-color-primary: #38bdf8; - --pst-color-secondary: #a78bfa; - --pst-color-accent: #22d3ee; - --pst-color-link: #38bdf8; +/* ── Code block sizing and shape ─────────────────────────────────────────── */ +/* Single border lives on pre; div.highlight only clips the radius. */ +div.highlight { + border-radius: 8px; + overflow: hidden; } -/* ── Code blocks: GitHub light (default) + GitHub dark (dark mode) ─────────── */ +.highlight pre { + font-size: 0.9rem; + line-height: 1.65; + border-radius: 8px; + border: 1px solid #d0d7de; /* override theme.css's var(--color-border) */ + margin-top: 0; /* theme adds a large top-margin — reset it */ + padding: 1rem 1.25rem; + font-feature-settings: + "liga" 1, + "calt" 1; +} -/* Light mode — GitHub light palette */ +html[data-theme="dark"] .highlight pre { + border-color: #30363d; +} + +/* Inline code */ +code.literal, +p code, +li code, +td code { + font-family: "JetBrains Mono", "Fira Code", "SF Mono", "Consolas", monospace; + font-size: 0.82em; + border-radius: 4px; + padding: 0.15em 0.4em; + background: #f3f4f6; + border: 1px solid #e2e4e8; + color: #c2185b; +} + +html[data-theme="dark"] code.literal, +html[data-theme="dark"] p code, +html[data-theme="dark"] li code, +html[data-theme="dark"] td code { + background: #161b22; + border-color: #30363d; + color: #ff7b72; +} + +/* ── Syntax highlighting — light palette (GitHub-inspired) ──────────────── */ +/* keywords: blue │ strings: green │ fn/class defs: purple */ +/* comments: gray │ numbers: blue │ variable names: neutral (no colour) */ div.highlight, .highlight pre { background: #f6f8fa; color: #24292f; } -.highlight pre span { - color: #24292f; -} +/* def, class, import, from, if, return, for, … → blue */ .highlight .k, .highlight .kn, .highlight .kd, .highlight .kr, -.highlight .kc { - color: #cf222e; - font-weight: 500; +.highlight .kc, +.highlight .kw { + color: #0550ae; + font-weight: 600; } +/* string literals → green */ .highlight .s, .highlight .s1, .highlight .s2, @@ -48,36 +96,44 @@ div.highlight, .highlight .se, .highlight .si, .highlight .sh { - color: #0a3069; + color: #116329; } +/* numbers → blue */ .highlight .mi, .highlight .mf, .highlight .mh, .highlight .mo { color: #0550ae; } +/* function names in definitions → purple */ .highlight .nf, .highlight .fm { - color: #6639ba; + color: #8250df; } +/* class names in definitions → purple */ .highlight .nc { - color: #953800; - font-weight: 500; + color: #8250df; + font-weight: 600; } +/* decorators (@property, @staticmethod, …) → purple */ .highlight .nd { - color: #953800; + color: #8250df; } +/* builtins (print, len, range, …) → blue */ .highlight .nb, .highlight .bp { - color: #0550ae; + color: #0969da; } +/* namespace / module names → neutral */ .highlight .nn { color: #24292f; } +/* operators → neutral */ .highlight .o, .highlight .ow { - color: #cf222e; + color: #24292f; } +/* comments → gray italic */ .highlight .c, .highlight .c1, .highlight .cm, @@ -86,33 +142,32 @@ div.highlight, color: #6e7781; font-style: italic; } +/* variable / param names → NEUTRAL (no colour; avoid painting everything) */ .highlight .n, .highlight .na, .highlight .nv, -.highlight .py { - color: #24292f; -} +.highlight .py, .highlight .p { color: #24292f; } -/* Dark mode — GitHub dark palette */ +/* ── Syntax highlighting — dark palette (GitHub Dark) ──────────────────── */ html[data-theme="dark"] div.highlight, html[data-theme="dark"] .highlight pre { - background: #0d1117 !important; - color: #e6edf3 !important; -} -html[data-theme="dark"] .highlight pre span { + background: #0d1117; color: #e6edf3; } +/* keywords → blue */ html[data-theme="dark"] .highlight .k, html[data-theme="dark"] .highlight .kn, html[data-theme="dark"] .highlight .kd, html[data-theme="dark"] .highlight .kr, -html[data-theme="dark"] .highlight .kc { - color: #ff7b72; - font-weight: 500; +html[data-theme="dark"] .highlight .kc, +html[data-theme="dark"] .highlight .kw { + color: #79c0ff; + font-weight: 600; } +/* strings → green */ html[data-theme="dark"] .highlight .s, html[data-theme="dark"] .highlight .s1, html[data-theme="dark"] .highlight .s2, @@ -120,35 +175,43 @@ html[data-theme="dark"] .highlight .sa, html[data-theme="dark"] .highlight .se, html[data-theme="dark"] .highlight .si, html[data-theme="dark"] .highlight .sh { - color: #a5d6ff; + color: #7ee787; } +/* numbers → blue */ html[data-theme="dark"] .highlight .mi, html[data-theme="dark"] .highlight .mf, html[data-theme="dark"] .highlight .mh { color: #79c0ff; } +/* function names → purple */ html[data-theme="dark"] .highlight .nf, html[data-theme="dark"] .highlight .fm { color: #d2a8ff; } +/* class names → purple */ html[data-theme="dark"] .highlight .nc { - color: #ffa657; - font-weight: 500; + color: #d2a8ff; + font-weight: 600; } +/* decorators → purple */ html[data-theme="dark"] .highlight .nd { - color: #ffa657; + color: #d2a8ff; } +/* builtins → blue */ html[data-theme="dark"] .highlight .nb, html[data-theme="dark"] .highlight .bp { color: #79c0ff; } +/* namespace names → neutral */ html[data-theme="dark"] .highlight .nn { color: #e6edf3; } +/* operators → neutral */ html[data-theme="dark"] .highlight .o, html[data-theme="dark"] .highlight .ow { - color: #ff7b72; + color: #e6edf3; } +/* comments → gray */ html[data-theme="dark"] .highlight .c, html[data-theme="dark"] .highlight .c1, html[data-theme="dark"] .highlight .cm, @@ -156,132 +219,27 @@ html[data-theme="dark"] .highlight .cp { color: #8b949e; font-style: italic; } +/* variable / param names → NEUTRAL */ html[data-theme="dark"] .highlight .n, html[data-theme="dark"] .highlight .na, html[data-theme="dark"] .highlight .nv, -html[data-theme="dark"] .highlight .py { - color: #e6edf3; -} +html[data-theme="dark"] .highlight .py, html[data-theme="dark"] .highlight .p { color: #e6edf3; } -.bd-main .bd-content .bd-article-container { - max-width: 900px; -} - -.bd-sidebar-primary { - font-size: 0.92rem; -} - -.sd-card { - border-radius: 14px; - box-shadow: none; - border: 1px solid var(--pst-color-border); -} - -.sd-card:hover { - border-color: var(--pst-color-primary); - transform: translateY(-1px); - transition: all 0.15s ease-in-out; -} - -.highlight pre { - border-radius: 12px; - font-family: var(--code-font); - font-size: 0.875rem; - line-height: 1.65; - padding: 1.1rem 1.25rem; - font-feature-settings: - "liga" 1, - "calt" 1; -} - -/* Inline code */ -code.literal, -p code, -li code, -td code { - font-family: var(--code-font); - font-size: 0.85em; - background: var(--pst-color-surface); - border: 1px solid var(--pst-color-border); - border-radius: 5px; - padding: 0.1em 0.4em; -} - -/* sphinx-copybutton: align with rounded blocks */ -div.highlight { - border-radius: 12px; - overflow: hidden; -} - -.bd-header { - box-shadow: none; - border-bottom: 1px solid var(--pst-color-border); -} - -/* Page title (h1): visually similar to h2 to reduce dominance */ -.bd-article h1 { - font-size: 1.75rem; - font-weight: 700; - line-height: 1.3; -} - -.bd-article h2 { - font-size: 1.4rem; - font-weight: 600; - line-height: 1.35; -} - -.bd-article h3 { - font-size: 1.15rem; - font-weight: 600; - line-height: 1.4; -} - -.bd-article h4 { - font-size: 1rem; - font-weight: 600; - line-height: 1.4; -} - -/* ── Sidebar nav section separators ───────────────────────────────────────── */ -/* Each top-level toctree becomes a
    inside - .bd-sidebar-primary .sidebar-primary-items__start nav. - We insert a thin rule above each group except the first. */ -.bd-sidebar-primary .bd-toc ul.current > li.toctree-l1:first-child, -.bd-sidebar-primary nav.bd-sidenav > ul > li { - /* no rule needed here */ -} - -/* Target the caption elements (section titles like "Getting Started") */ -.bd-sidebar-primary .caption-text { - font-size: 0.7rem; - font-weight: 700; - letter-spacing: 0.08em; - text-transform: uppercase; - color: var(--pst-color-text-muted); - padding-top: 0.75rem; - margin-top: 0.5rem; - border-top: 1px solid var(--pst-color-border); - display: block; -} - -/* Remove the border-top from the very first caption */ -.bd-sidebar-primary .toctree-wrapper > ul > li:first-child .caption-text, -.bd-sidebar-primary nav > ul > li.has-children:first-child > .caption-text { - border-top: none; - padding-top: 0; - margin-top: 0; +/* ── List item spacing — Tailwind prose adds too much gap ────────────────── */ +/* Scoped to #content so sidebar/nav lists are unaffected */ +#content ul li, +#content ol li { + margin-top: 0.2rem; + margin-bottom: 0.2rem; + line-height: 1.55; } -/* ── Navbar: GitHub icon + text label ─────────────────────────────────────── */ -/* pydata-sphinx-theme hides .icon-link-name by default; reveal it */ -.navbar-icon-link .icon-link-name { - display: inline !important; - font-size: 0.85rem; - font-weight: 500; - margin-left: 0.3rem; - vertical-align: middle; +/* Numpydoc field lists (Parameters, Returns, etc.) */ +#content dl > dd > ul li, +#content dl > dd > ol li { + margin-top: 0.1rem; + margin-bottom: 0.1rem; } From f3db4ef9bb98c9bb66319e76c70799be634f0b30 Mon Sep 17 00:00:00 2001 From: Manish Kumar Date: Sun, 17 May 2026 00:31:52 +0200 Subject: [PATCH 6/7] docs: homepage and readme update --- README.md | 4 +- docs/homepage.md | 102 ++++++++++++++++++------------------- docs/requirements_docs.txt | 14 ++--- 3 files changed, 58 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index 929246b..e3d7a10 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@
    - + [![PyPI](https://img.shields.io/pypi/v/deeptab)](https://pypi.org/project/deeptab) ![PyPI - Downloads](https://img.shields.io/pypi/dm/deeptab) @@ -15,7 +15,7 @@
    -

    deeptab: Tabular Deep Learning Made Simple

    +

    DeepTab: Tabular Deep Learning Made Simple

    deeptab is a Python library for tabular deep learning. It includes models that leverage the Mamba (State Space Model) architecture, as well as other popular models like TabTransformer, FTTransformer, TabM and tabular ResNets. Check out our paper `Mambular: A Sequential Model for Tabular Deep Learning`, available [here](https://arxiv.org/abs/2408.06291). Also check out our paper introducing [TabulaRNN](https://arxiv.org/pdf/2411.17207) and analyzing the efficiency of NLP inspired tabular models. diff --git a/docs/homepage.md b/docs/homepage.md index f68d632..45a80f4 100644 --- a/docs/homepage.md +++ b/docs/homepage.md @@ -1,4 +1,4 @@ -# deeptab: Tabular Deep Learning Made Simple +# DeepTab: Tabular Deep Learning Made Simple deeptab is a Python library for tabular deep learning. It includes models that leverage the Mamba (State Space Model) architecture, as well as other popular models like TabTransformer, FTTransformer, TabM and tabular ResNets. Check out our paper `Mambular: A Sequential Model for Tabular Deep Learning`, available on [arXiv](https://arxiv.org/abs/2408.06291). Also check out our paper introducing [TabulaRNN](https://arxiv.org/pdf/2411.17207) and analyzing the efficiency of NLP inspired tabular models. @@ -229,69 +229,69 @@ Here's how you can implement a custom model with deeptab: 1. **First, define your config:** The configuration class allows you to specify hyperparameters and other settings for your model. This can be done using a simple dataclass. - ```python - from dataclasses import dataclass - - @dataclass - class MyConfig: - lr: float = 1e-04 - lr_patience: int = 10 - weight_decay: float = 1e-06 - lr_factor: float = 0.1 - ``` +```python +from dataclasses import dataclass + +@dataclass +class MyConfig: + lr: float = 1e-04 + lr_patience: int = 10 + weight_decay: float = 1e-06 + lr_factor: float = 0.1 +``` 2. **Second, define your model:** Define your custom model just as you would for an `nn.Module`. The main difference is that you will inherit from `BaseModel` and use the provided feature information to construct your layers. To integrate your model into the existing API, you only need to define the architecture and the forward pass. - ```python - from deeptab.base_models import BaseModel - from deeptab.utils.get_feature_dimensions import get_feature_dimensions - import torch - import torch.nn - - class MyCustomModel(BaseModel): - def __init__( - self, - cat_feature_info, - num_feature_info, - num_classes: int = 1, - config=None, - **kwargs, - ): - super().__init__(**kwargs) - self.save_hyperparameters(ignore=["cat_feature_info", "num_feature_info"]) - - input_dim = get_feature_dimensions(num_feature_info, cat_feature_info) - - self.linear = nn.Linear(input_dim, num_classes) - - def forward(self, num_features, cat_features): - x = num_features + cat_features - x = torch.cat(x, dim=1) - - # Pass through linear layer - output = self.linear(x) - return output - ``` +```python +from deeptab.base_models import BaseModel +from deeptab.utils.get_feature_dimensions import get_feature_dimensions +import torch +import torch.nn + +class MyCustomModel(BaseModel): + def __init__( + self, + cat_feature_info, + num_feature_info, + num_classes: int = 1, + config=None, + **kwargs, + ): + super().__init__(**kwargs) + self.save_hyperparameters(ignore=["cat_feature_info", "num_feature_info"]) + + input_dim = get_feature_dimensions(num_feature_info, cat_feature_info) + + self.linear = nn.Linear(input_dim, num_classes) + + def forward(self, num_features, cat_features): + x = num_features + cat_features + x = torch.cat(x, dim=1) + + # Pass through linear layer + output = self.linear(x) + return output +``` 3. **Leverage the deeptab API:** You can build a regression, classification, or distributional regression model that can leverage all of deeptab's built-in methods by using the following: - ```python - from deeptab.models import SklearnBaseRegressor +```python +from deeptab.models import SklearnBaseRegressor - class MyRegressor(SklearnBaseRegressor): - def __init__(self, **kwargs): - super().__init__(model=MyCustomModel, config=MyConfig, **kwargs) - ``` +class MyRegressor(SklearnBaseRegressor): + def __init__(self, **kwargs): + super().__init__(model=MyCustomModel, config=MyConfig, **kwargs) +``` 4. **Train and evaluate your model:** You can now fit, evaluate, and predict with your custom model just like with any other deeptab model. For classification or distributional regression, inherit from `SklearnBaseClassifier` or `SklearnBaseLSS` respectively. - ```python - regressor = MyRegressor(numerical_preprocessing="ple") - regressor.fit(X_train, y_train, max_epochs=50) - ``` +```python +regressor = MyRegressor(numerical_preprocessing="ple") +regressor.fit(X_train, y_train, max_epochs=50) +``` # Custom Training diff --git a/docs/requirements_docs.txt b/docs/requirements_docs.txt index 2b3c0f4..1552169 100644 --- a/docs/requirements_docs.txt +++ b/docs/requirements_docs.txt @@ -1,16 +1,12 @@ setuptools -sphinx==6.2.1 -sphinx-autodoc-typehints==1.23.0 -numpydoc==1.7.0 +sphinx==9.1.0 +sphinx-autodoc-typehints>=3.0 +numpydoc>=1.8 nbsphinx==0.9.4 ipython -myst-parser==3.0.1 -m2r2==0.3.3.post2 -sphinx-copybutton==0.5.2 +myst-parser>=4.0 sphinx-togglebutton==0.3.2 -sphinx-book-theme==1.1.2 -pandoc==2.3 -sphinx-rtd-theme==2.0.0 +sphinxawesome-theme>=6.0 readthedocs-sphinx-ext==2.2.5 lxml-html-clean==0.4.0 pydata-sphinx-theme==0.15.2 From 0a6c0241470b81724359071e6e700455344b7184 Mon Sep 17 00:00:00 2001 From: Manish Kumar Date: Sun, 17 May 2026 00:48:12 +0200 Subject: [PATCH 7/7] docs: ignore third party warning --- docs/conf.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 49b0780..4edb5f3 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -83,6 +83,11 @@ # Usually you set "language" from the command line for these cases. language = "en" +# Suppress RemovedInSphinx10Warning from nbsphinx (upstream issue, not ours) +filterwarnings = [ + "ignore::sphinx.deprecation.RemovedInSphinx10Warning", +] + # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. @@ -133,11 +138,10 @@ # Use the theme's own permalink icon html_permalinks_icon = Icons.permalinks_icon -# On API reference pages the page TOC would list every class and every method — -# hundreds of entries. Suppress it there; keep it on regular doc pages. +# On API reference pages suppress the page TOC (would list every class/method). +# Non-API pages fall back to the theme's default sidebars, so no ** needed. html_sidebars = { "api/**": ["sidebar_main_nav_links.html"], - "**": ["sidebar_main_nav_links.html", "sidebar_toc.html"], } # The name of an image file (relative to this directory) to place at the top