Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve static typing #1021

Merged
merged 5 commits into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,11 @@ jobs:
- { os: macos-latest, python: "3.12", toxenv: py312-sphinx74, cache: ~/Library/Caches/pip }
- { os: windows-latest, python: "3.12", toxenv: py312-sphinx74, cache: ~\AppData\Local\pip\Cache }

# linting
# linting/other
# - any OS, using most recent interpreter
- { os: ubuntu-latest, python: "3.12", toxenv: ruff, cache: ~/.cache/pip }
- { os: ubuntu-latest, python: "3.12", toxenv: pylint, cache: ~/.cache/pip }
- { os: ubuntu-latest, python: "3.12", toxenv: mypy, cache: ~/.cache/pip }

steps:
- uses: actions/checkout@v4
Expand Down
25 changes: 25 additions & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[mypy]

# ignore optional jupyter_sphinx module
[mypy-jupyter_sphinx.*]
ignore_missing_imports = True

# ignore optional nbsphinx module
[mypy-nbsphinx.*]
ignore_missing_imports = True

# ignore optional sphinx_diagrams module
[mypy-sphinx_diagrams.*]
ignore_missing_imports = True

# ignore optional sphinx_gallery module
[mypy-sphinx_gallery.*]
ignore_missing_imports = True

# ignore optional sphinx_toolbox module
[mypy-sphinx_toolbox.*]
ignore_missing_imports = True

# ignore optional sphinxcontrib.mermaid module
[mypy-sphinxcontrib.mermaid.*]
ignore_missing_imports = True
13 changes: 7 additions & 6 deletions sphinxcontrib/confluencebuilder/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,16 @@
# load autosummary extension if available to add additional nodes
try:
from sphinx.ext import autosummary
has_autosummary = True
except ImportError:
autosummary = None
has_autosummary = False

# load imgmath extension if available to handle math configuration options
try:
from sphinx.ext import imgmath
has_imgmath = True
except ImportError:
imgmath = None
has_imgmath = False

__version__ = '2.7.0.dev0'

Expand Down Expand Up @@ -383,7 +385,7 @@ def confluence_autosummary_support(app):
app: the sphinx application
"""

if autosummary:
if has_autosummary:
for ext in app.extensions.values():
if ext.name == 'sphinx.ext.autosummary':
app.registry.add_translation_handlers(
Expand Down Expand Up @@ -423,9 +425,8 @@ def confluence_imgmath_support(app):
app: the sphinx application
"""

if imgmath is not None:
if 'sphinx.ext.imgmath' not in app.config.extensions:
imgmath.setup(app)
if has_imgmath and 'sphinx.ext.imgmath' not in app.config.extensions:
imgmath.setup(app)


def confluence_remove_mathnodemigrator(app):
Expand Down
43 changes: 0 additions & 43 deletions sphinxcontrib/confluencebuilder/assets.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from sphinxcontrib.confluencebuilder.compat import docutils_findall as findall
from sphinxcontrib.confluencebuilder.logger import ConfluenceLogger as logger
from sphinxcontrib.confluencebuilder.std.confluence import INVALID_CHARS
from sphinxcontrib.confluencebuilder.std.confluence import SUPPORTED_IMAGE_TYPES
from sphinxcontrib.confluencebuilder.util import ConfluenceUtil
from sphinxcontrib.confluencebuilder.util import find_env_abspath

Expand Down Expand Up @@ -347,45 +346,3 @@ def _interpret_asset_path(self, node):
logger.verbose(f'failed to find path: {path}')

return abs_path


class ConfluenceSupportedImages:
def __init__(self):
"""
confluence support images

Defines an iterable instance of mime types of supported images types on
a Confluence instance. While a typical list can suffice to bind to a
builder's `supported_image_types` definition, this instance provides the
ability to register additional mime types (via configuration) if
supported by a Confluence instance. This provides flexibility for newer
Confluence versions as well as custom instances which support their own
custom image types.
"""
self._mime_types = list(SUPPORTED_IMAGE_TYPES)

def __getitem__(self, key):
"""
iterable evaulation of self[key]

Args:
key: the key to evaluate

Returns:
the value for this key
"""
return self._mime_types[key]

def register(self, type_):
"""
register a mime type to support

Register an additional mime type to support over the internal list of
supported types. This call has no effect if the type is already
registered.

Args:
type_: the mime type to add
"""
if type_ not in self._mime_types:
self._mime_types.append(type_)
7 changes: 4 additions & 3 deletions sphinxcontrib/confluencebuilder/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from sphinx.locale import _ as SL
from sphinx.util.display import status_iterator
from sphinxcontrib.confluencebuilder.assets import ConfluenceAssetManager
from sphinxcontrib.confluencebuilder.assets import ConfluenceSupportedImages
from sphinxcontrib.confluencebuilder.compat import docutils_findall as findall
from sphinxcontrib.confluencebuilder.config import process_ask_configs
from sphinxcontrib.confluencebuilder.config.checks import validate_configuration
Expand All @@ -30,6 +29,7 @@
from sphinxcontrib.confluencebuilder.publisher import ConfluencePublisher
from sphinxcontrib.confluencebuilder.state import ConfluenceState
from sphinxcontrib.confluencebuilder.std.confluence import CONFLUENCE_MAX_WIDTH
from sphinxcontrib.confluencebuilder.std.confluence import SUPPORTED_IMAGE_TYPES
from sphinxcontrib.confluencebuilder.storage.index import generate_storage_format_domainindex
from sphinxcontrib.confluencebuilder.storage.index import generate_storage_format_genindex
from sphinxcontrib.confluencebuilder.storage.search import generate_storage_format_search
Expand All @@ -52,7 +52,7 @@ class ConfluenceBuilder(Builder):
default_translator_class = ConfluenceStorageFormatTranslator
name = 'confluence'
format = 'confluence_storage'
supported_image_types = ConfluenceSupportedImages()
supported_image_types = SUPPORTED_IMAGE_TYPES
supported_linkcode = True
supported_remote_images = True

Expand Down Expand Up @@ -114,7 +114,8 @@ def init(self):

if self.config.confluence_additional_mime_types:
for type_ in self.config.confluence_additional_mime_types:
self.supported_image_types.register(type_)
if type_ not in self.supported_image_types:
self.supported_image_types.append(type_)

if 'graphviz_output_format' in self.config: # noqa: SIM401
self.graphviz_output_format = self.config['graphviz_output_format']
Expand Down
37 changes: 19 additions & 18 deletions sphinxcontrib/confluencebuilder/state.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: BSD-2-Clause
# Copyright Sphinx Confluence Builder Contributors (AUTHORS)

from __future__ import annotations
import hashlib
from sphinxcontrib.confluencebuilder.config.exceptions import ConfluenceConfigError
from sphinxcontrib.confluencebuilder.logger import ConfluenceLogger as logger
Expand All @@ -15,15 +16,15 @@ class ConfluenceState:
operation. This includes, but not limited to, remember title names for
documents, tracking reference identifiers to other document names and more.
"""
doc2uploadId = {}
doc2parentDoc = {}
doc2title = {}
doc2ttd = {}
refid2target = {}
title2doc = {}
doc2uploadId: dict[str, int] = {}
doc2parentDoc: dict[str, str] = {}
doc2title: dict[str, str] = {}
doc2ttd: dict[str, int] = {}
refid2target: dict[str, str] = {}
title2doc: dict[str, str] = {}

@staticmethod
def register_parent_docname(docname, parent_docname):
def register_parent_docname(docname: str, parent_docname: str):
"""
register a parent docname for a provided docname

Expand All @@ -41,7 +42,7 @@ def register_parent_docname(docname, parent_docname):
logger.verbose(f'setting parent of {docname} to: {parent_docname}')

@staticmethod
def register_target(refid, target, overwrite=False):
def register_target(refid: str, target: str, *, overwrite: bool=False):
"""
register a reference to a specific (anchor) target

Expand All @@ -62,7 +63,7 @@ def register_target(refid, target, overwrite=False):
logger.verbose(f'mapping {refid} to target: {target}{postfix}')

@staticmethod
def register_title(docname, title, config):
def register_title(docname: str, title: str, config) -> str:
"""
register the title for the provided document name

Expand Down Expand Up @@ -127,7 +128,7 @@ def register_title(docname, title, config):
return title

@staticmethod
def register_toctree_depth(docname, depth):
def register_toctree_depth(docname: str, depth: int):
"""
register the toctree-depth for the provided document name

Expand All @@ -142,7 +143,7 @@ def register_toctree_depth(docname, depth):
logger.verbose(f'track {docname} toc-depth: {depth}')

@staticmethod
def register_upload_id(docname, id_):
def register_upload_id(docname: str, id_: int):
"""
register a page (upload) identifier for a docname

Expand Down Expand Up @@ -175,7 +176,7 @@ def reset():
ConfluenceState.title2doc.clear()

@staticmethod
def parent_docname(docname):
def parent_docname(docname: str) -> str | None:
"""
return the parent docname (if any) for a provided docname

Expand All @@ -184,7 +185,7 @@ def parent_docname(docname):
return ConfluenceState.doc2parentDoc.get(docname)

@staticmethod
def target(refid):
def target(refid: str) -> str | None:
"""
return the (anchor) target for a provided reference

Expand All @@ -193,7 +194,7 @@ def target(refid):
return ConfluenceState.refid2target.get(refid)

@staticmethod
def title(docname, default=None):
def title(docname: str, default: str | None = None) -> str | None:
"""
return the title value for a provided docname

Expand All @@ -202,7 +203,7 @@ def title(docname, default=None):
return ConfluenceState.doc2title.get(docname, default)

@staticmethod
def toctree_depth(docname):
def toctree_depth(docname: str) -> int | None:
"""
return the toctree-depth value for a provided docname

Expand All @@ -211,7 +212,7 @@ def toctree_depth(docname):
return ConfluenceState.doc2ttd.get(docname)

@staticmethod
def upload_id(docname):
def upload_id(docname: str) -> int | None:
"""
return the confluence (upload) page id for the provided docname

Expand All @@ -220,7 +221,7 @@ def upload_id(docname):
return ConfluenceState.doc2uploadId.get(docname)

@staticmethod
def _format_postfix(postfix, docname, config):
def _format_postfix(postfix: str, docname: str, config) -> str:
"""
Format a postfix that may have placeholders.
All placeholders used must be supported otherwise an error is raised
Expand All @@ -239,7 +240,7 @@ def _format_postfix(postfix, docname, config):
return postfix

@staticmethod
def _create_docname_unique_hash(docname, config):
def _create_docname_unique_hash(docname: str, config) -> str:
"""
Create a unique(ish) hash for the given source file to avoid collisions
when pushing pages to confluence.
Expand Down
3 changes: 2 additions & 1 deletion sphinxcontrib/confluencebuilder/storage/translator.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# Copyright Sphinx Confluence Builder Contributors (AUTHORS)
# Copyright 2018-2020 by the Sphinx team (sphinx-doc/sphinx#AUTHORS)

from __future__ import annotations
from contextlib import suppress
from docutils import nodes
from functools import wraps
Expand Down Expand Up @@ -85,7 +86,7 @@ def _wrapper(self, *args, **kwargs):

class ConfluenceStorageFormatTranslator(ConfluenceBaseTranslator):
__tracked_deprecated = False
_tracked_unknown_code_lang = []
_tracked_unknown_code_lang: list[str] = []

"""
confluence storage format extension translator
Expand Down
22 changes: 12 additions & 10 deletions sphinxcontrib/confluencebuilder/transmute/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# SPDX-License-Identifier: BSD-2-Clause
# Copyright Sphinx Confluence Builder Contributors (AUTHORS)

from contextlib import suppress
from docutils import nodes
from sphinx.util.math import wrap_displaymath
from sphinxcontrib.confluencebuilder.compat import docutils_findall as findall
Expand All @@ -23,20 +22,23 @@
from sphinx.ext.graphviz import GraphvizError
from sphinx.ext.graphviz import graphviz
from sphinx.ext.graphviz import render_dot
has_graphviz = True
except ImportError:
graphviz = None
has_graphviz = False

# load imgmath extension if available to handle math node pre-processing
try:
from sphinx.ext import imgmath
has_imgmath = True
except ImportError:
imgmath = None
has_imgmath = False

# load inheritance_diagram extension if available to handle node pre-processing
inheritance_diagram = None
if graphviz:
with suppress(ImportError):
from sphinx.ext import inheritance_diagram
try:
from sphinx.ext import inheritance_diagram
has_inheritance_diagram = True
except ImportError:
has_inheritance_diagram = False


def doctree_transmute(builder, doctree):
Expand Down Expand Up @@ -112,7 +114,7 @@ def prepare_math_images(builder, doctree):
if builder.config.confluence_latex_macro:
return

if imgmath is None:
if not has_imgmath:
return

# convert Confluence LaTeX blocks into image blocks
Expand Down Expand Up @@ -203,7 +205,7 @@ def replace_graphviz_nodes(builder, doctree):
if 'ext-graphviz' in restricted:
return

if graphviz is None:
if not has_graphviz:
return

# graphviz's render_dot call expects a translator to be passed in; mock a
Expand Down Expand Up @@ -258,7 +260,7 @@ def replace_inheritance_diagram(builder, doctree):
if 'ext-inheritance_diagram' in restricted:
return

if inheritance_diagram is None:
if not has_graphviz or not has_inheritance_diagram:
return

# graphviz's render_dot call expects a translator to be passed in; mock
Expand Down
Loading