diff --git a/docs/conf.py b/docs/conf.py index befa80a..9c744b1 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,39 +1,16 @@ -# -*- coding: utf-8 -*- -# -# Configuration file for the Sphinx documentation builder. -# -# This file does only contain a selection of the most common options. For a -# full list see the documentation: -# http://www.sphinx-doc.org/en/master/config - import importlib.metadata import re -# -- Project information ----------------------------------------------------- - project = "sphinx-json-schema-spec" author = "Julian Berman" copyright = "2013, " + author -# version: The short X.Y version -# release: The full version, including alpha/beta/rc tags. release = importlib.metadata.version("sphinx_json_schema_spec") version = release.partition("-")[0] - -# -- General configuration --------------------------------------------------- - -# If your documentation needs a minimal Sphinx version, state it here. -# -# needs_sphinx = "1.0" - +language = "en" default_role = "any" -primary_domain = "rst" - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named "sphinx.ext.*") or your custom -# ones. extensions = [ "sphinx.ext.autodoc", "sphinx.ext.autosectionlabel", @@ -44,172 +21,33 @@ "sphinx.ext.todo", "sphinx_json_schema_spec", "sphinxcontrib.spelling", + "sphinxext.opengraph", ] -# Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# -# source_suffix = [".rst", ".md"] -source_suffix = ".rst" +pygments_style = "lovelace" +pygments_dark_style = "one-dark" -# The master toctree document. -master_doc = "index" - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = "en" - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = [u"_build", "Thumbs.db", ".DS_Store"] - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = "sphinx" - - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# html_theme = "furo" -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -# -# html_theme_options = {} - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -# html_static_path = ["_static"] - -# Custom sidebar templates, must be a dictionary that maps document names -# to template names. -# -# The default sidebars (for documents that don't match any pattern) are -# defined by theme itself. Builtin themes are using these templates by -# default: ``["localtoc.html", "relations.html", "sourcelink.html", -# "searchbox.html"]``. -# -# html_sidebars = {} - - -# -- Options for HTMLHelp output --------------------------------------------- - -# Output file base name for HTML help builder. -htmlhelp_basename = "sphinxjsonschemaspecdoc" - - -# -- Options for LaTeX output ------------------------------------------------ - -latex_elements = { - # The paper size ("letterpaper" or "a4paper"). - # - # "papersize": "letterpaper", - - # The font size ("10pt", "11pt" or "12pt"). - # - # "pointsize": "10pt", - - # Additional stuff for the LaTeX preamble. - # - # "preamble": "", - - # Latex figure (float) alignment - # - # "figure_align": "htbp", -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - ( - master_doc, - "Sphinx JSON Schema Spec.tex", - project, - author, - "manual", - ), -] - -# -- Options for manual page output ------------------------------------------ - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ( - master_doc, - project, - project, - [author], - 1, - ), -] +def entire_domain(host): + return r"http.?://" + re.escape(host) + r"($|/.*)" -# -- Options for Texinfo output ---------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ( - master_doc, - project, - project, - author, - project, - "", - "Miscellaneous", - ), +linkcheck_ignore = [ + entire_domain("img.shields.io"), + "https://github.com/python-jsonschema/sphinx-json-schema-spec/actions", + "https://github.com/python-jsonschema/sphinx-json-schema-spec/workflows/CI/badge.svg", # noqa: E501 ] +# = Extensions = -# -- Options for Epub output ------------------------------------------------- - -# Bibliographic Dublin Core info. -epub_title = project - -# The unique identifier of the text. This can be a ISBN number -# or the project homepage. -# -# epub_identifier = "" - -# A unique identification for the text. -# -# epub_uid = "" - -# A list of files that should not be packed into the epub file. -epub_exclude_files = ["search.html"] - - -# -- Extension configuration ------------------------------------------------- - -# -- Options for autodoc extension ------------------------------------------- - -autodoc_default_options = { - "members": True, - "member-order": "bysource", -} - -# -- Options for autosectionlabel extension ---------------------------------- +# -- autosectionlabel -- autosectionlabel_prefix_document = True -# -- Options for intersphinx extension --------------------------------------- +# -- intersphinx -- -# Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = { "jsonschema": ( "https://python-jsonschema.readthedocs.io/en/latest/", None, @@ -219,16 +57,7 @@ "sphinx": ("https://www.sphinx-doc.org/en/master/", None), } -# -- Options for the linkcheck builder ------------------------------------ - +# -- sphinxcontrib-spelling -- -def entire_domain(host): - return r"http.?://" + re.escape(host) + r"($|/.*)" - - -linkcheck_ignore = [ - entire_domain("codecov.io"), - entire_domain("img.shields.io"), - "https://github.com/python-jsonschema/sphinx-json-schema-spec/actions", - "https://github.com/python-jsonschema/sphinx-json-schema-spec/workflows/CI/badge.svg", # noqa: E501 -] +spelling_word_list_filename = "spelling-wordlist.txt" +spelling_show_suggestions = True diff --git a/docs/requirements.in b/docs/requirements.in index cff356e..2ff9d8d 100644 --- a/docs/requirements.in +++ b/docs/requirements.in @@ -2,3 +2,4 @@ file:.#egg=sphinx_json_schema_spec furo sphinx>=5.1 sphinxcontrib-spelling>5 +sphinxext-opengraph diff --git a/docs/requirements.txt b/docs/requirements.txt index b4d2626..8a1d301 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,22 +1,28 @@ # -# This file is autogenerated by pip-compile with python 3.11 -# To update, run: +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: # -# pip-compile docs/requirements.in +# pip-compile --resolver=backtracking docs/requirements.in # -alabaster==0.7.12 +alabaster==0.7.13 # via sphinx -babel==2.11.0 +babel==2.12.1 # via sphinx -beautifulsoup4==4.11.1 +beautifulsoup4==4.12.2 # via furo -certifi==2022.12.7 +certifi==2023.5.7 # via requests -charset-normalizer==2.1.1 +charset-normalizer==3.1.0 # via requests -docutils==0.19 +contourpy==1.0.7 + # via matplotlib +cycler==0.11.0 + # via matplotlib +docutils==0.20.1 # via sphinx -furo==2022.12.7 +fonttools==4.39.4 + # via matplotlib +furo==2023.5.20 # via -r docs/requirements.in idna==3.4 # via requests @@ -24,42 +30,59 @@ imagesize==1.4.1 # via sphinx jinja2==3.1.2 # via sphinx +kiwisolver==1.4.4 + # via matplotlib lxml==4.9.2 # via sphinx-json-schema-spec -markupsafe==2.1.1 +markupsafe==2.1.2 # via jinja2 -packaging==22.0 - # via sphinx +matplotlib==3.7.1 + # via sphinxext-opengraph +numpy==1.24.3 + # via + # contourpy + # matplotlib +packaging==23.1 + # via + # matplotlib + # sphinx +pillow==9.5.0 + # via matplotlib pyenchant==3.2.2 # via sphinxcontrib-spelling -pygments==2.13.0 +pygments==2.15.1 # via # furo # sphinx -pytz==2022.6 - # via babel -requests==2.28.1 +pyparsing==3.0.9 + # via matplotlib +python-dateutil==2.8.2 + # via matplotlib +requests==2.31.0 # via sphinx +six==1.16.0 + # via python-dateutil snowballstemmer==2.2.0 # via sphinx -soupsieve==2.3.2.post1 +soupsieve==2.4.1 # via beautifulsoup4 -sphinx==5.3.0 +sphinx==7.0.1 # via # -r docs/requirements.in # furo # sphinx-basic-ng # sphinx-json-schema-spec # sphinxcontrib-spelling + # sphinxext-opengraph sphinx-basic-ng==1.0.0b1 # via furo file:.#egg=sphinx_json_schema_spec # via -r docs/requirements.in -sphinxcontrib-applehelp==1.0.2 +sphinxcontrib-applehelp==1.0.4 # via sphinx sphinxcontrib-devhelp==1.0.2 # via sphinx -sphinxcontrib-htmlhelp==2.0.0 +sphinxcontrib-htmlhelp==2.0.1 # via sphinx sphinxcontrib-jsmath==1.0.1 # via sphinx @@ -67,7 +90,9 @@ sphinxcontrib-qthelp==1.0.3 # via sphinx sphinxcontrib-serializinghtml==1.1.5 # via sphinx -sphinxcontrib-spelling==7.7.0 +sphinxcontrib-spelling==8.0.0 + # via -r docs/requirements.in +sphinxext-opengraph==0.8.2 # via -r docs/requirements.in -urllib3==1.26.13 +urllib3==2.0.2 # via requests diff --git a/docs/spelling_wordlist.txt b/docs/spelling-wordlist.txt similarity index 100% rename from docs/spelling_wordlist.txt rename to docs/spelling-wordlist.txt diff --git a/noxfile.py b/noxfile.py index 2d3934d..e8b54b1 100644 --- a/noxfile.py +++ b/noxfile.py @@ -3,6 +3,7 @@ import nox ROOT = Path(__file__).parent +PYPROJECT = ROOT / "pyproject.toml" DOCS = ROOT / "docs" PACKAGE = ROOT / "sphinx_json_schema_spec" @@ -19,44 +20,43 @@ def _session(fn): return _session -@session(python=["3.7", "3.8", "3.9", "3.10", "3.11", "pypy3"]) +@session(python=["3.8", "3.9", "3.10", "3.11", "pypy3"]) def tests(session): - session.install("pytest", str(ROOT)) - session.run("pytest", "--verbosity=3") + session.install("pytest", ROOT) + session.run("pytest", *session.posargs, PACKAGE) + + +@session() +def audit(session): + session.install("pip-audit", ROOT) + session.run("python", "-m", "pip_audit") @session(tags=["build"]) def build(session): session.install("build") tmpdir = session.create_tmp() - session.run("python", "-m", "build", str(ROOT), "--outdir", tmpdir) + session.run("python", "-m", "build", ROOT, "--outdir", tmpdir) @session(tags=["style"]) def readme(session): session.install("build", "twine") tmpdir = session.create_tmp() - session.run("python", "-m", "build", str(ROOT), "--outdir", tmpdir) + session.run("python", "-m", "build", ROOT, "--outdir", tmpdir) session.run("python", "-m", "twine", "check", tmpdir + "/*") @session(tags=["style"]) def style(session): - session.install( - "flake8", - "flake8-broken-line", - "flake8-bugbear", - "flake8-commas", - "flake8-quotes", - "flake8-tidy-imports", - ) - session.run("python", "-m", "flake8", str(PACKAGE), __file__) + session.install("ruff") + session.run("ruff", "check", ROOT) @session() def typing(session): - session.install("mypy", "types-docutils", "types-lxml", str(ROOT)) - session.run("python", "-m", "mypy", str(PACKAGE)) + session.install("mypy", "types-docutils", "types-lxml", ROOT) + session.run("python", "-m", "mypy", PACKAGE) @session(tags=["docs"]) @@ -74,7 +74,7 @@ def typing(session): ], ) def docs(session, builder): - session.install("-r", str(DOCS / "requirements.txt")) + session.install("-r", DOCS / "requirements.txt") tmpdir = Path(session.create_tmp()) argv = ["-n", "-T", "-W"] if builder != "spelling": @@ -85,8 +85,8 @@ def docs(session, builder): "sphinx", "-b", builder, - str(DOCS), - str(tmpdir / builder), + DOCS, + tmpdir / builder, *argv, ) @@ -98,4 +98,4 @@ def docs_style(session): "pygments", "pygments-github-lexers", ) - session.run("python", "-m", "doc8", "--max-line-length", "1000", str(DOCS)) + session.run("python", "-m", "doc8", "--config", PYPROJECT, DOCS) diff --git a/pyproject.toml b/pyproject.toml index 45d9c5d..18f89a1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,8 +9,8 @@ source = "vcs" name = "sphinx_json_schema_spec" description = "Sphinx support for the JSON Schema specifications" readme = "README.rst" -requires-python = ">=3.7" license = {text = "MIT"} +requires-python = ">=3.8" keywords = ["json schema", "jsonschema", "data validation", "sphinx", "json"] authors = [ {email = "Julian+sphinx-json-schema-spec@GrayVines.com"}, @@ -21,36 +21,75 @@ classifiers = [ "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", + "Programming Language :: Python", "Programming Language :: Python :: 3", - "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 :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", - "Programming Language :: Python", "Framework :: Sphinx :: Extension", "Topic :: Documentation :: Sphinx", + "Topic :: File Formats :: JSON :: JSON Schema", ] dynamic = ["version"] dependencies = [ "lxml", "sphinx>=5.1.1", - "importlib_metadata;python_version<'3.8'", ] [project.urls] +Documentation = "https://sphinx-json-schema-spec.readthedocs.io/" Homepage = "https://github.com/python-jsonschema/sphinx-json-schema-spec" Issues = "https://github.com/python-jsonschema/sphinx-json-schema-spec/issues/" Funding = "https://github.com/sponsors/Julian" Source = "https://github.com/python-jsonschema/sphinx-json-schema-spec" [tool.doc8] -max-line-length=1000 +ignore = [ + "D001", # one sentence per line, so max length doesn't make sense +] [tool.isort] +combine_as_imports = true from_first = true include_trailing_comma = true multi_line_output = 3 + +[tool.ruff] +line-length = 79 +target-version = "py38" +select = ["B", "D", "E", "F", "Q", "UP", "W"] +ignore = [ + # raise SomeException(...) is fine. + "B904", + # It's fine to not have docstrings for magic methods. + "D105", + # This rule makes diffs uglier when expanding docstrings (and it's uglier) + "D200", + # No blank lines before docstrings. + "D203", + # Start docstrings on the second line. + "D212", + # This rule misses sassy docstrings ending with ! or ?. + "D400", + # Section headers should end with a colon not a newline + "D406", + # Underlines aren't needed + "D407", + # Plz spaces after section headers + "D412", + # We support 3.8 + 3.9 + "UP007", +] +extend-exclude = ["suite"] + +[tool.ruff.flake8-quotes] +docstring-quotes = "double" + +[tool.ruff.per-file-ignores] +"docs/*" = ["ANN", "D"] +"sphinx_json_schema_spec/tests/*" = ["ANN", "D"] +"noxfile.py" = ["ANN", "D"] diff --git a/sphinx_json_schema_spec/__init__.py b/sphinx_json_schema_spec/__init__.py index 0a82c8c..fa7acf7 100644 --- a/sphinx_json_schema_spec/__init__.py +++ b/sphinx_json_schema_spec/__init__.py @@ -1,3 +1,6 @@ +""" +Sphinx support for interlinking to the JSON Schema specifications. +""" from contextlib import suppress from datetime import datetime from pathlib import Path @@ -35,7 +38,6 @@ def setup(app): the Sphinx application context """ - app.add_config_value("cache_path", "_cache", "") CACHE = Path(app.config.cache_path) @@ -70,7 +72,6 @@ def fetch_or_load(cache_path, url): the URL of the document """ - version = metadata.version("sphinx-json-schema-spec") headers = {"User-Agent": f"sphinx-json-schema-spec v{version}"} @@ -111,7 +112,7 @@ def keyword(name, raw_text, text, lineno, inliner): the name of the role in the document - raw_source (str): + raw_text (str): the raw text (role with argument) @@ -134,7 +135,6 @@ def keyword(name, raw_text, text, lineno, inliner): a 2-tuple of nodes to insert into the document and an iterable of system messages, both possibly empty """ - hardcoded = HARDCODED.get(text) if hardcoded is not None: return [nodes.reference(raw_text, text, refuri=hardcoded)], [] @@ -153,9 +153,7 @@ def keyword(name, raw_text, text, lineno, inliner): uri = urljoin(vocabulary_url, header.find("a").attrib["href"]) break else: - inliner.reporter.warning( - "Didn't find a target for {0}".format(text), - ) + inliner.reporter.warning(f"Didn't find a target for {text}") uri = BASE_URL reference = nodes.reference(raw_text, text, refuri=uri) @@ -165,7 +163,9 @@ def keyword(name, raw_text, text, lineno, inliner): def missing_reference(glossary): - + """ + Get callbacked for Sphinx's missing reference hook. + """ terms = { link.lstrip("#") for _, _, link, _ in glossary.iterlinks() @@ -176,7 +176,6 @@ def _missing_reference(app, env, node, contnod): """ Resolve a reference to a JSON Schema Glossary term. """ - if node["reftype"] != "term": return