Skip to content

Commit

Permalink
refactor: Drop support for MkDocs < 1.4, modernize usages
Browse files Browse the repository at this point in the history
  • Loading branch information
oprypin committed Oct 26, 2023
1 parent 370a61d commit b61d4d1
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 53 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Expand Up @@ -32,7 +32,7 @@ dependencies = [
"Jinja2>=2.11.1",
"Markdown>=3.3",
"MarkupSafe>=1.1",
"mkdocs>=1.2",
"mkdocs>=1.4",
"mkdocs-autorefs>=0.3.1",
"pymdown-extensions>=6.3",
"importlib-metadata>=4.6; python_version < '3.10'",
Expand Down
3 changes: 1 addition & 2 deletions src/mkdocstrings/extension.py
Expand Up @@ -72,8 +72,7 @@ def __init__(
Arguments:
parser: A `markdown.blockparser.BlockParser` instance.
md: A `markdown.Markdown` instance.
config: The [configuration][mkdocstrings.plugin.MkdocstringsPlugin.config_scheme]
of the `mkdocstrings` plugin.
config: The [configuration][mkdocstrings.plugin.PluginConfig] of the `mkdocstrings` plugin.
handlers: The handlers container.
autorefs: The autorefs plugin instance.
"""
Expand Down
96 changes: 49 additions & 47 deletions src/mkdocstrings/plugin.py
Expand Up @@ -22,8 +22,8 @@
from typing import TYPE_CHECKING, Any, BinaryIO, Callable, Iterable, List, Mapping, Tuple, TypeVar
from urllib import request

from mkdocs.config.config_options import Type as MkType
from mkdocs.config.config_options import Dir, Optional
from mkdocs.config import Config
from mkdocs.config import config_options as opt
from mkdocs.plugins import BasePlugin
from mkdocs.utils import write_file
from mkdocs_autorefs.plugin import AutorefsPlugin
Expand All @@ -34,7 +34,6 @@

if TYPE_CHECKING:
from jinja2.environment import Environment
from mkdocs.config import Config
from mkdocs.config.defaults import MkDocsConfig

if sys.version_info < (3, 10):
Expand Down Expand Up @@ -63,38 +62,15 @@ def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
return wrapper


class MkdocstringsPlugin(BasePlugin):
"""An `mkdocs` plugin.
This plugin defines the following event hooks:
- `on_config`
- `on_env`
- `on_post_build`
class PluginConfig(Config):
"""The configuration options of `mkdocstrings`, written in `mkdocs.yml`."""

Check the [Developing Plugins](https://www.mkdocs.org/user-guide/plugins/#developing-plugins) page of `mkdocs`
for more information about its plugin system.
"""

config_scheme: tuple[tuple[str, MkType]] = ( # type: ignore[assignment]
("handlers", MkType(dict, default={})),
("default_handler", MkType(str, default="python")),
("custom_templates", Optional(Dir(exists=True))),
("enable_inventory", MkType(bool, default=None)),
("enabled", MkType(bool, default=True)),
)
handlers = opt.Type(dict, default={})
"""
The configuration options of `mkdocstrings`, written in `mkdocs.yml`.
Global configuration of handlers.
Available options are:
- **`handlers`**: Global configuration of handlers. You can set global configuration per handler, applied everywhere,
but overridable in each "autodoc" instruction. Example:
- **`default_handler`**: The default handler to use. The value is the name of the handler module. Default is "python".
- **`custom_templates`**: Location of custom templates to use when rendering API objects. Value should be the path of
a directory relative to the MkDocs configuration file.
- **`enable_inventory`**: Whether to enable object inventory creation.
- **`enabled`**: Whether to enable the plugin. Default is true. If false, *mkdocstrings* will not collect or render anything.
You can set global configuration per handler, applied everywhere,
but overridable in each "autodoc" instruction. Example:
```yaml
plugins:
Expand All @@ -110,6 +86,32 @@ class MkdocstringsPlugin(BasePlugin):
```
"""

default_handler = opt.Type(str, default="python")
"""The default handler to use. The value is the name of the handler module. Default is "python"."""
custom_templates = opt.Optional(opt.Dir(exists=True)),
"""Location of custom templates to use when rendering API objects.
Value should be the path of a directory relative to the MkDocs configuration file.
"""
enable_inventory = opt.Optional(opt.Type(bool))
"""Whether to enable object inventory creation."""
enabled = opt.Type(bool, default=True)
"""Whether to enable the plugin. Default is true. If false, *mkdocstrings* will not collect or render anything."""


class MkdocstringsPlugin(BasePlugin[PluginConfig]):
"""An `mkdocs` plugin.
This plugin defines the following event hooks:
- `on_config`
- `on_env`
- `on_post_build`
Check the [Developing Plugins](https://www.mkdocs.org/user-guide/plugins/#developing-plugins) page of `mkdocs`
for more information about its plugin system.
"""

css_filename = "assets/_mkdocstrings.css"

def __init__(self) -> None:
Expand Down Expand Up @@ -152,41 +154,41 @@ def on_config(self, config: MkDocsConfig) -> MkDocsConfig | None:
return config
log.debug("Adding extension to the list")

theme_name = config["theme"].name or os.path.dirname(config["theme"].dirs[0])
theme_name = config.theme.name or os.path.dirname(config.theme.dirs[0])

to_import: InventoryImportType = []
for handler_name, conf in self.config["handlers"].items():
for handler_name, conf in self.config.handlers.items():
for import_item in conf.pop("import", ()):
if isinstance(import_item, str):
import_item = {"url": import_item} # noqa: PLW2901
to_import.append((handler_name, import_item))

extension_config = {
"theme_name": theme_name,
"mdx": config["markdown_extensions"],
"mdx_configs": config["mdx_configs"],
"mdx": config.markdown_extensions,
"mdx_configs": config.mdx_configs,
"mkdocstrings": self.config,
"mkdocs": config,
}
self._handlers = Handlers(extension_config)

try:
# If autorefs plugin is explicitly enabled, just use it.
autorefs = config["plugins"]["autorefs"]
autorefs = config.plugins["autorefs"]
log.debug(f"Picked up existing autorefs instance {autorefs!r}")
except KeyError:
# Otherwise, add a limited instance of it that acts only on what's added through `register_anchor`.
autorefs = AutorefsPlugin()
autorefs.scan_toc = False
config["plugins"]["autorefs"] = autorefs
config.plugins["autorefs"] = autorefs
log.debug(f"Added a subdued autorefs instance {autorefs!r}")
# Add collector-based fallback in either case.
autorefs.get_fallback_anchor = self.handlers.get_anchors

mkdocstrings_extension = MkdocstringsExtension(extension_config, self.handlers, autorefs)
config["markdown_extensions"].append(mkdocstrings_extension)
config.markdown_extensions.append(mkdocstrings_extension)

config["extra_css"].insert(0, self.css_filename) # So that it has lower priority than user files.
config.extra_css.insert(0, self.css_filename) # So that it has lower priority than user files.

self._inv_futures = {}
if to_import:
Expand All @@ -210,7 +212,7 @@ def inventory_enabled(self) -> bool:
Returns:
Whether the inventory is enabled.
"""
inventory_enabled = self.config["enable_inventory"]
inventory_enabled = self.config.enable_inventory
if inventory_enabled is None:
inventory_enabled = any(handler.enable_inventory for handler in self.handlers.seen_handlers)
return inventory_enabled
Expand All @@ -222,9 +224,9 @@ def plugin_enabled(self) -> bool:
Returns:
Whether the plugin is enabled.
"""
return self.config["enabled"]
return self.config.enabled

def on_env(self, env: Environment, config: Config, *args: Any, **kwargs: Any) -> None: # noqa: ARG002
def on_env(self, env: Environment, config: MkDocsConfig, *args: Any, **kwargs: Any) -> None: # noqa: ARG002
"""Extra actions that need to happen after all Markdown rendering and before HTML rendering.
Hook for the [`on_env` event](https://www.mkdocs.org/user-guide/plugins/#on_env).
Expand All @@ -236,12 +238,12 @@ def on_env(self, env: Environment, config: Config, *args: Any, **kwargs: Any) ->
return
if self._handlers:
css_content = "\n".join(handler.extra_css for handler in self.handlers.seen_handlers)
write_file(css_content.encode("utf-8"), os.path.join(config["site_dir"], self.css_filename))
write_file(css_content.encode("utf-8"), os.path.join(config.site_dir, self.css_filename))

if self.inventory_enabled:
log.debug("Creating inventory file objects.inv")
inv_contents = self.handlers.inventory.format_sphinx()
write_file(inv_contents, os.path.join(config["site_dir"], "objects.inv"))
write_file(inv_contents, os.path.join(config.site_dir, "objects.inv"))

if self._inv_futures:
log.debug(f"Waiting for {len(self._inv_futures)} inventory download(s)")
Expand All @@ -256,12 +258,12 @@ def on_env(self, env: Environment, config: Config, *args: Any, **kwargs: Any) ->
loader_name = loader.__func__.__qualname__
log.error(f"Couldn't load inventory {import_item} through {loader_name}: {error}") # noqa: TRY400
for page, identifier in results.items():
config["plugins"]["autorefs"].register_url(page, identifier)
config.plugins["autorefs"].register_url(page, identifier)
self._inv_futures = {}

def on_post_build(
self,
config: Config, # noqa: ARG002
config: MkDocsConfig, # noqa: ARG002
**kwargs: Any, # noqa: ARG002
) -> None:
"""Teardown the handlers.
Expand Down
6 changes: 3 additions & 3 deletions tests/conftest.py
Expand Up @@ -8,7 +8,7 @@
import pytest
from markdown.core import Markdown
from mkdocs import config
from mkdocs.config.defaults import get_schema
from mkdocs.config.defaults import MkDocsConfig

if TYPE_CHECKING:
from pathlib import Path
Expand All @@ -19,7 +19,7 @@
@pytest.fixture(name="mkdocs_conf")
def fixture_mkdocs_conf(request: pytest.FixtureRequest, tmp_path: Path) -> Iterator[config.Config]:
"""Yield a MkDocs configuration object."""
conf = config.Config(schema=get_schema()) # type: ignore[call-arg]
conf = MkDocsConfig()
while hasattr(request, "_parent_request") and hasattr(request._parent_request, "_parent_request"):
request = request._parent_request

Expand Down Expand Up @@ -53,6 +53,6 @@ def fixture_plugin(mkdocs_conf: config.Config) -> MkdocstringsPlugin:


@pytest.fixture(name="ext_markdown")
def fixture_ext_markdown(mkdocs_conf: config.Config) -> Markdown:
def fixture_ext_markdown(mkdocs_conf: MkDocsConfig) -> Markdown:
"""Return a Markdown instance with MkdocstringsExtension."""
return Markdown(extensions=mkdocs_conf["markdown_extensions"], extension_configs=mkdocs_conf["mdx_configs"])

0 comments on commit b61d4d1

Please sign in to comment.