From 09158cf2e85ee33e8f1b774a0e44dda0132db570 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Mon, 2 Mar 2026 17:31:50 -0800 Subject: [PATCH 1/8] MAINT: dropping sphinx<7 and python<3.10 versions --- .github/workflows/tests.yml | 2 +- setup.py | 13 +++++++------ sphinx_tabs/tabs.py | 4 +--- tests/conftest.py | 2 +- tox.ini | 8 +++++--- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7d7efc5..74e4f87 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] steps: - uses: actions/checkout@v6 diff --git a/setup.py b/setup.py index 4ecbffa..2c78e19 100755 --- a/setup.py +++ b/setup.py @@ -24,12 +24,12 @@ def get_version(): include_package_data=True, url="https://github.com/executablebooks/sphinx-tabs", license="MIT", - python_requires=">=3.7", - install_requires=["sphinx>=1.8", "pygments", "docutils"], + python_requires=">=3.10", + install_requires=["sphinx>=7", "pygments", "docutils"], extras_require={ "testing": [ "coverage", - "pytest>=7.1,<8", + "pytest>=7.1", "pytest-cov", "pytest-regressions", "pygments", @@ -47,10 +47,11 @@ def get_version(): "License :: OSI Approved :: MIT License", "Natural Language :: English", "Operating System :: OS Independent", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Programming Language :: Python", "Topic :: Documentation :: Sphinx", "Topic :: Documentation", diff --git a/sphinx_tabs/tabs.py b/sphinx_tabs/tabs.py index bad665e..09aed8a 100644 --- a/sphinx_tabs/tabs.py +++ b/sphinx_tabs/tabs.py @@ -304,9 +304,7 @@ def update_context(app, pagename, templatename, context, doctree): visitor = _FindTabsDirectiveVisitor(doctree) doctree.walk(visitor) - include_assets_in_all_pages = False - if sphinx.version_info >= (4, 1, 0): - include_assets_in_all_pages = app.registry.html_assets_policy == "always" + include_assets_in_all_pages = app.registry.html_assets_policy == "always" if visitor.found_tabs_directive or include_assets_in_all_pages: if not app.config.sphinx_tabs_disable_css_loading: diff --git a/tests/conftest.py b/tests/conftest.py index 9f4af3a..97a9f96 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -190,7 +190,7 @@ def get_sphinx_app_output(): def get(app, buildername="html", filename="index.html", encoding="utf-8"): outpath = Path(app.srcdir) / "_build" / buildername / filename if not outpath.exists(): - raise IOError("No output file exists: {}".format(outpath.as_posix())) + raise OSError(f"No output file exists: {outpath.as_posix()}") return outpath.read_text(encoding=encoding) diff --git a/tox.ini b/tox.ini index 67b0cdf..49be570 100644 --- a/tox.ini +++ b/tox.ini @@ -4,16 +4,18 @@ # then run `tox` or `tox -- {pytest args}` # run in parallel using `tox -p` [tox] -envlist = py{311,312,313,314}-sphinx{7,8,9},docs +envlist = py{310,311,312,313,314}-sphinx{7,8,9},docs -[testenv:py{311,312,313,314}-sphinx{7,8,9}] +[testenv:py{310,311,312,313,314}-sphinx{7,8,9}] extras = testing deps = sphinx7: sphinx>=7,<8 sphinx8: sphinx>=8,<9 sphinx9: sphinx>=9,<10 recreate = false -commands = pytest {posargs} +commands = + pip freeze + pytest {posargs} [testenv:docs] whitelist_externals = rm From 785f5b1a64ab5bbeeeb94e33a594d9091b023084 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Mon, 2 Mar 2026 17:43:23 -0800 Subject: [PATCH 2/8] Updating tox file --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 49be570..cd8602b 100644 --- a/tox.ini +++ b/tox.ini @@ -18,7 +18,7 @@ commands = pytest {posargs} [testenv:docs] -whitelist_externals = rm +allowlist_externals = rm recreate = false commands = rm -rf docs/_build From e1de97fba3ca687a68e498daeb5031715cfa7c74 Mon Sep 17 00:00:00 2001 From: Diego Prada Date: Mon, 2 Mar 2026 17:48:49 -0600 Subject: [PATCH 3/8] Modernize packaging and improve Sphinx 9 compatibility --- sphinx_tabs/tabs.py | 11 +++++++++-- tests/test_build.py | 8 +++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/sphinx_tabs/tabs.py b/sphinx_tabs/tabs.py index 09aed8a..cd55872 100644 --- a/sphinx_tabs/tabs.py +++ b/sphinx_tabs/tabs.py @@ -27,6 +27,11 @@ LEXER_MAP[short_name] = lexer[0] +def _get_env_app(env): + """Return Sphinx app without triggering deprecated BuildEnvironment.app.""" + return getattr(env, "_app", None) or env.app + + def get_compatible_builders(app): builders = [ "html", @@ -103,7 +108,8 @@ def run(self): self.state.nested_parse(self.content, self.content_offset, node) - if self.env.app.builder.name in get_compatible_builders(self.env.app): + app = _get_env_app(self.env) + if app.builder.name in get_compatible_builders(app): tablist = SphinxTabsTablist() tablist["role"] = "tablist" tablist["aria-label"] = "Tabbed content" @@ -187,7 +193,8 @@ def run(self): self.state.nested_parse(self.content[1:], self.content_offset, panel) - if self.env.app.builder.name not in get_compatible_builders(self.env.app): + app = _get_env_app(self.env) + if app.builder.name not in get_compatible_builders(app): # Use base docutils classes outer_node = nodes.container() tab = nodes.container() diff --git a/tests/test_build.py b/tests/test_build.py index 4a21690..94be76a 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -2,6 +2,7 @@ import pytest import sphinx from sphinx.application import Sphinx +from rinoh.resource import ResourceNotFound @pytest.mark.sphinx(testroot="basic") @@ -74,7 +75,12 @@ def test_custom_lexer(app, check_asset_links): def test_rinohtype_pdf( app, status, warning, check_build_success, get_sphinx_app_doctree ): - app.build() + try: + app.build() + except ResourceNotFound as err: + if "Tex Gyre Heros" in str(err): + pytest.skip("Tex Gyre Heros typeface is not available in this environment") + raise check_build_success(status, warning) get_sphinx_app_doctree(app, regress=True) # Doesn't currently regression test pdf output From b45e4ea53e0348c60bf1e5bfbb5514130fb5310d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Mon, 2 Mar 2026 17:48:02 -0800 Subject: [PATCH 4/8] Update deprecated BS4 usage --- tests/conftest.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 97a9f96..98401c5 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,4 +1,3 @@ -import os import pytest from pathlib import Path from bs4 import BeautifulSoup @@ -96,7 +95,7 @@ def read(app, buildername="html", filename="index.html", encoding="utf-8"): body = soup.select("div.body")[0] body.append(soup.new_tag("div", **{"class": "clearer"})) - doc_div = soup.findAll("div", {"class": "documentwrapper"})[0] + doc_div = soup.find_all("div", {"class": "documentwrapper"})[0] doc = doc_div.prettify() else: From 96dead268aa0ad28fcd80e390a991e0c7af1ce57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Mon, 2 Mar 2026 18:00:05 -0800 Subject: [PATCH 5/8] MAINT: remove more old version workarounds --- tests/test_build.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/test_build.py b/tests/test_build.py index 94be76a..fcc1d3c 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -1,7 +1,4 @@ -import sys import pytest -import sphinx -from sphinx.application import Sphinx from rinoh.resource import ResourceNotFound @@ -69,9 +66,6 @@ def test_custom_lexer(app, check_asset_links): @pytest.mark.noautobuild @pytest.mark.sphinx("rinoh", testroot="rinohtype-pdf") -@pytest.mark.skipif( - sys.version_info < (3, 8), reason="Unknown dependency conflict in lower versions" -) def test_rinohtype_pdf( app, status, warning, check_build_success, get_sphinx_app_doctree ): From b2be1a1ba05b67e12686bced6f865fcc1b569a3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Mon, 2 Mar 2026 18:00:17 -0800 Subject: [PATCH 6/8] MAINT: ensure we fail on warnings, adding exceptions for 3rd party --- setup.cfg | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 setup.cfg diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..d7dbda6 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,9 @@ +[tool:pytest] +xfail_strict = true +addopts = --color=yes --doctest-continue-on-failure +filterwarnings = + error + # Deprecation triggered in rinoh + ignore:nodes.Node.traverse:DeprecationWarning + # More rinoh warning + ignore:TeX Gyre Pagella does not include:rinoh.warnings.RinohWarning \ No newline at end of file From d97b624452990dadb389c436f98be868f661cbea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Mon, 2 Mar 2026 18:05:12 -0800 Subject: [PATCH 7/8] Adding pending deprecation to ignore list --- setup.cfg | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup.cfg b/setup.cfg index d7dbda6..174710f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -5,5 +5,7 @@ filterwarnings = error # Deprecation triggered in rinoh ignore:nodes.Node.traverse:DeprecationWarning + # Same as above, but for python3.10 it is a pending deprecation + ignore:nodes.Node.traverse:PendingDeprecationWarning # More rinoh warning ignore:TeX Gyre Pagella does not include:rinoh.warnings.RinohWarning \ No newline at end of file From 8e1368e6a203d96a98de593e0f9c8805bc647504 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Mon, 2 Mar 2026 18:05:33 -0800 Subject: [PATCH 8/8] Fix linter --- setup.cfg | 2 +- sphinx_tabs/tabs.py | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/setup.cfg b/setup.cfg index 174710f..09bb679 100644 --- a/setup.cfg +++ b/setup.cfg @@ -8,4 +8,4 @@ filterwarnings = # Same as above, but for python3.10 it is a pending deprecation ignore:nodes.Node.traverse:PendingDeprecationWarning # More rinoh warning - ignore:TeX Gyre Pagella does not include:rinoh.warnings.RinohWarning \ No newline at end of file + ignore:TeX Gyre Pagella does not include:rinoh.warnings.RinohWarning diff --git a/sphinx_tabs/tabs.py b/sphinx_tabs/tabs.py index cd55872..18157da 100644 --- a/sphinx_tabs/tabs.py +++ b/sphinx_tabs/tabs.py @@ -3,8 +3,6 @@ import base64 from pathlib import Path from functools import partial -import sphinx - from docutils import nodes from docutils.parsers.rst import directives