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.cfg b/setup.cfg new file mode 100644 index 0000000..09bb679 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,11 @@ +[tool:pytest] +xfail_strict = true +addopts = --color=yes --doctest-continue-on-failure +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 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..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 @@ -27,6 +25,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 +106,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 +191,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() @@ -304,9 +309,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..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: @@ -190,7 +189,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/tests/test_build.py b/tests/test_build.py index 4a21690..fcc1d3c 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -1,7 +1,5 @@ -import sys import pytest -import sphinx -from sphinx.application import Sphinx +from rinoh.resource import ResourceNotFound @pytest.mark.sphinx(testroot="basic") @@ -68,13 +66,15 @@ 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 ): - 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 diff --git a/tox.ini b/tox.ini index 67b0cdf..cd8602b 100644 --- a/tox.ini +++ b/tox.ini @@ -4,19 +4,21 @@ # 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 +allowlist_externals = rm recreate = false commands = rm -rf docs/_build