From e19071b5cab120721ac898da8a87ca97dff23aa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Tue, 1 Mar 2022 20:22:33 +0100 Subject: [PATCH 01/15] docs: Improve `pycon` no-prompt-selection recipe --- docs/recipes.md | 49 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/docs/recipes.md b/docs/recipes.md index c1a38bbb..d0f92d38 100644 --- a/docs/recipes.md +++ b/docs/recipes.md @@ -296,15 +296,17 @@ themselves, better reflecting our public API. show_submodules: no ``` -## Prevent selection of `>>>` in Python code blocks +## Prevent selection of prompts and output in Python code blocks -To prevent the selection of `>>>` in Python code blocks, -you can use the `pycon` syntax highlighting on your code block, -and add some CSS rules to your site using MkDocs `extra_css` option: +To prevent the selection of `>>>`, `...` and output in Python "Console" code blocks, +you can use the `pycon` syntax highlighting on your code blocks, +and add global CSS rules to your site using MkDocs `extra_css` option: ````md ```pycon ->>> print("Hello mkdocstrings!") +>>> for word in ("Hello", "mkdocstrings!"): +... print(word, end=" ") +Hello mkdocstrings! ``` ```` @@ -319,6 +321,39 @@ extra_css: - css/code_select.css ``` +!!! warning + The `.highlight .gp, .highlight .go` CSS selector can have unintended side-effects. + To target `pycon` code blocks more specifically, you can configure the + `pymdownx.highlight` extension to use Pygments and set language classes + on code blocks: + + ```yaml title="mkdocs.yml" + markdown_extensions: + - pymdownx.highlight: + use_pygments: true + pygments_lang_class: true + ``` + + Then you can update the CSS selector like this: + + ```css title="docs/css/code_select.css" + .language-pycon .gp, .language-pycon .go { /* Generic.Prompt, Generic.Output */ + user-select: none; + } + ``` + +If you don't want to enable this globally, +you can still use `style` tags in the relevant pages, +with more accurate CSS selectors: + +```html + +``` + Try to select the following code block's text: ```pycon ->>> print("Hello mkdocstrings!") +>>> for word in ("Hello", "mkdocstrings!"): +... print(word, end=" ") +Hello mkdocstrings! ``` From eb822cb11ec065da0b1277299aae4ffeeffadc6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Sat, 2 Apr 2022 16:57:08 +0200 Subject: [PATCH 02/15] refactor: Deprecate BaseCollector and BaseRenderer The BaseCollector and BaseRenderer are merged into the BaseHandler (as mixins for now). Developers are still able to create collectors and renderers using these deprecated base classes, and pass instances of them when creating their handler. All the methods of the deprecated bases can now be defined on the BaseHandler subclass itself. Handlers can then be instantiated by passing the handler's name, the theme and the optional custom templates folder name/path. Reasoning: often times, the renderer and the collector need to communicate or share data. For example, the Crystal renderer uses the collector to lookup names when creating cross-references. The Python handlers are able to filter members when collecting/returning data, and need the same members list when rendering, to order the elements based on that list. This change is the first of two, where the second change will deprecate the use of `selection` and `rendering` keys in the YAML options or MkDocs configuration, in favor of a single `options` key that both the collection and rendering process will share. --- src/mkdocstrings/extension.py | 8 +- src/mkdocstrings/handlers/base.py | 150 +++++++++++++++++++++++++----- src/mkdocstrings/plugin.py | 2 +- tests/test_extension.py | 4 +- 4 files changed, 132 insertions(+), 32 deletions(-) diff --git a/src/mkdocstrings/extension.py b/src/mkdocstrings/extension.py index 60efaade..3b0e54fb 100644 --- a/src/mkdocstrings/extension.py +++ b/src/mkdocstrings/extension.py @@ -122,7 +122,7 @@ def run(self, parent: Element, blocks: MutableSequence[str]) -> None: # The final HTML is inserted as opaque to subsequent processing, and only revealed at the end. el.text = self.md.htmlStash.store(html) # So we need to duplicate the headings directly (and delete later), just so 'toc' can pick them up. - headings = handler.renderer.get_headings() + headings = handler.get_headings() el.extend(headings) page = self._autorefs.current_page @@ -179,7 +179,7 @@ def _process_block( log.debug("Collecting data") try: - data: CollectorItem = handler.collector.collect(identifier, selection) + data: CollectorItem = handler.collect(identifier, selection) except CollectionError as exception: log.error(str(exception)) if PluginError is SystemExit: # When MkDocs 1.2 is sufficiently common, this can be dropped. @@ -188,12 +188,12 @@ def _process_block( if not self._updated_env: log.debug("Updating renderer's env") - handler.renderer._update_env(self.md, self._config) # noqa: WPS437 (protected member OK) + handler._update_env(self.md, self._config) # noqa: WPS437 (protected member OK) self._updated_env = True log.debug("Rendering templates") try: - rendered = handler.renderer.render(data, rendering) + rendered = handler.render(data, rendering) except TemplateNotFound as exc: theme_name = self._config["theme_name"] log.error( diff --git a/src/mkdocstrings/handlers/base.py b/src/mkdocstrings/handlers/base.py index 51e74bab..3bdf2336 100644 --- a/src/mkdocstrings/handlers/base.py +++ b/src/mkdocstrings/handlers/base.py @@ -8,9 +8,10 @@ - `teardown`, that will teardown all the cached handlers, and then clear the cache. """ +from __future__ import annotations + import importlib import warnings -from abc import ABC, abstractmethod from contextlib import suppress from pathlib import Path from typing import Any, Dict, Iterable, List, Optional, Sequence @@ -58,7 +59,7 @@ def do_any(seq: Sequence, attribute: str = None) -> bool: return any(_[attribute] for _ in seq) -class BaseRenderer(ABC): +class BaseRenderer: """The base renderer class. Inherit from this class to implement a renderer. @@ -74,7 +75,7 @@ class BaseRenderer(ABC): fallback_theme: str = "" extra_css = "" - def __init__(self, handler: str, theme: str, custom_templates: Optional[str] = None, directory: str = None) -> None: + def __init__(self, handler: str, theme: str, custom_templates: Optional[str] = None) -> None: """Initialize the object. If the given theme is not supported (it does not exist), it will look for a `fallback_theme` attribute @@ -84,19 +85,14 @@ def __init__(self, handler: str, theme: str, custom_templates: Optional[str] = N handler: The name of the handler. theme: The name of theme to use. custom_templates: Directory containing custom templates. - directory: Deprecated and renamed as `handler`. """ - # TODO: remove at some point - if directory: - warnings.warn( - "The 'directory' keyword parameter is deprecated and renamed 'handler'. ", - DeprecationWarning, - ) - if not handler: - handler = directory - paths = [] + # TODO: remove once BaseRenderer is merged into BaseHandler + self._handler = handler + self._theme = theme + self._custom_templates = custom_templates + themes_dir = self.get_templates_dir(handler) paths.append(themes_dir / theme) @@ -123,7 +119,6 @@ def __init__(self, handler: str, theme: str, custom_templates: Optional[str] = N self._headings: List[Element] = [] self._md: Markdown = None # type: ignore # To be populated in `update_env`. - @abstractmethod def render(self, data: CollectorItem, config: dict) -> str: """Render a template using provided data and configuration options. @@ -313,7 +308,7 @@ def _update_env(self, md: Markdown, config: dict): self.update_env(new_md, config) -class BaseCollector(ABC): +class BaseCollector: """The base collector class. Inherit from this class to implement a collector. @@ -322,7 +317,6 @@ class BaseCollector(ABC): You can also implement the `teardown` method. """ - @abstractmethod def collect(self, identifier: str, config: dict) -> CollectorItem: """Collect data given an identifier and selection configuration. @@ -348,7 +342,7 @@ def teardown(self) -> None: """ -class BaseHandler: +class BaseHandler(BaseCollector, BaseRenderer): """The base handler class. Inherit from this class to implement a handler. @@ -359,20 +353,126 @@ class BaseHandler: domain: The cross-documentation domain/language for this handler. enable_inventory: Whether this handler is interested in enabling the creation of the `objects.inv` Sphinx inventory file. + fallback_config: The configuration used to collect item during autorefs fallback. """ domain: str = "default" enable_inventory: bool = False + fallback_config: dict = {} - def __init__(self, collector: BaseCollector, renderer: BaseRenderer) -> None: + # TODO: once the BaseCollector and BaseRenderer classes are removed, + # stop accepting the 'handler' parameter, and instead set a 'name' attribute on the Handler class. + # Then make the 'handler' parameter in 'get_templates_dir' optional, and use the class 'name' by default. + def __init__(self, *args: str | BaseCollector | BaseRenderer, **kwargs: str | BaseCollector | BaseRenderer) -> None: """Initialize the object. Arguments: - collector: A collector instance. - renderer: A renderer instance. + *args: Collector and renderer, or handler name, theme and custom_templates. + **kwargs: Same thing, but with keyword arguments. + + Raises: + ValueError: When the givin parameters are invalid. """ - self.collector = collector - self.renderer = renderer + # The method accepts *args and **kwargs temporarily, + # to support the transition period where the BaseCollector + # and BaseRenderer are deprecated, and the BaseHandler + # can be instantiated with both instances of collector/renderer, + # or renderer parameters, as positional parameters. + # Supported: + # handler = Handler(collector, renderer) + # handler = Handler(collector=collector, renderer=renderer) + # handler = Handler("python", "material") + # handler = Handler("python", "material", "templates") + # handler = Handler(handler="python", theme="material") + # handler = Handler(handler="python", theme="material", custom_templates="templates") + # Invalid: + # handler = Handler("python", "material", collector, renderer) + # handler = Handler("python", theme="material", collector=collector) + # handler = Handler(collector, renderer, "material") + # handler = Handler(collector, renderer, theme="material") + # handler = Handler(collector) + # handler = Handler(renderer) + # etc. + + collector = None + renderer = None + + # parsing positional arguments + str_args = [] + for arg in args: + if isinstance(arg, BaseCollector): + collector = arg + elif isinstance(arg, BaseRenderer): + renderer = arg + elif isinstance(arg, str): + str_args.append(arg) + + while len(str_args) != 3: + str_args.append(None) # type: ignore[arg-type] + + handler, theme, custom_templates = str_args + + # fetching values from keyword arguments + if "collector" in kwargs: + collector = kwargs.pop("collector") # type: ignore[assignment] + if "renderer" in kwargs: + renderer = kwargs.pop("renderer") # type: ignore[assignment] + if "handler" in kwargs: + handler = kwargs.pop("handler") # type: ignore[assignment] + if "theme" in kwargs: + theme = kwargs.pop("theme") # type: ignore[assignment] + if "custom_templates" in kwargs: + custom_templates = kwargs.pop("custom_templates") # type: ignore[assignment] + + if collector is None and renderer is not None or collector is not None and renderer is None: + raise ValueError("both 'collector' and 'renderer' must be provided") + + if collector is not None: + warnings.warn( + DeprecationWarning( + "The BaseCollector class is deprecated, and passing an instance of it " + "to your handler is deprecated as well. Instead, define the `collect` and `teardown` " + "methods directly on your handler class." + ) + ) + self.collector = collector + self.collect = collector.collect # type: ignore[assignment] + self.teardown = collector.teardown # type: ignore[assignment] + + if renderer is not None: + if {handler, theme, custom_templates} != {None}: + raise ValueError( + "'handler', 'theme' and 'custom_templates' must all be None when providing a renderer instance" + ) + warnings.warn( + DeprecationWarning( + "The BaseRenderer class is deprecated, and passing an instance of it " + "to your handler is deprecated as well. Instead, define the `render` method" + "directly on your handler class (as well as other methods and attributes like " + "`get_templates_dir`, `get_anchors`, `update_env` and `fallback_theme`, `extra_css`)." + ) + ) + self.renderer = renderer + self.render = renderer.render # type: ignore[assignment] + self.get_templates_dir = renderer.get_templates_dir # type: ignore[assignment] + self.get_anchors = renderer.get_anchors # type: ignore[assignment] + self.do_convert_markdown = renderer.do_convert_markdown # type: ignore[assignment] + self.do_heading = renderer.do_heading # type: ignore[assignment] + self.get_headings = renderer.get_headings # type: ignore[assignment] + self.update_env = renderer.update_env # type: ignore[assignment] + self._update_env = renderer._update_env # type: ignore[assignment] # noqa: WPS437 + self.fallback_theme = renderer.fallback_theme + self.extra_css = renderer.extra_css + renderer.__class__.__init__( # noqa: WPS609 + self, + renderer._handler, # noqa: WPS437 + renderer._theme, # noqa: WPS437 + renderer._custom_templates, # noqa: WPS437 + ) + else: + if handler is None or theme is None: + raise ValueError("'handler' and 'theme' cannot be None") + BaseRenderer.__init__(self, handler, theme, custom_templates) # noqa: WPS609 class Handlers: @@ -403,9 +503,9 @@ def get_anchors(self, identifier: str) -> Sequence[str]: A tuple of strings - anchors without '#', or an empty tuple if there isn't any identifier familiar with it. """ for handler in self._handlers.values(): - fallback_config = getattr(handler.collector, "fallback_config", {}) + fallback_config = getattr(handler, "fallback_config", {}) try: - anchors = handler.renderer.get_anchors(handler.collector.collect(identifier, fallback_config)) + anchors = handler.get_anchors(handler.collect(identifier, fallback_config)) except CollectionError: continue if anchors: @@ -490,5 +590,5 @@ def seen_handlers(self) -> Iterable[BaseHandler]: def teardown(self) -> None: """Teardown all cached handlers and clear the cache.""" for handler in self.seen_handlers: - handler.collector.teardown() + handler.teardown() self._handlers.clear() diff --git a/src/mkdocstrings/plugin.py b/src/mkdocstrings/plugin.py index a30c7b10..4f2fdda6 100644 --- a/src/mkdocstrings/plugin.py +++ b/src/mkdocstrings/plugin.py @@ -224,7 +224,7 @@ def on_env(self, env, config: Config, **kwargs): - Gather results from background inventory download tasks. """ if self._handlers: - css_content = "\n".join(handler.renderer.extra_css for handler in self.handlers.seen_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)) if self.inventory_enabled: diff --git a/tests/test_extension.py b/tests/test_extension.py index 69e9aaef..8039e240 100644 --- a/tests/test_extension.py +++ b/tests/test_extension.py @@ -127,9 +127,9 @@ def test_use_custom_handler(ext_markdown): def test_dont_register_every_identifier_as_anchor(plugin): """Assert that we don't preemptively register all identifiers of a rendered object.""" - renderer = plugin._handlers.get_handler("python").renderer # noqa: WPS437 + handler = plugin._handlers.get_handler("python") # noqa: WPS437 ids = {"id1", "id2", "id3"} - renderer.get_anchors = lambda _: ids + handler.get_anchors = lambda _: ids plugin.md.convert("::: tests.fixtures.headings") autorefs = plugin.md.parser.blockprocessors["mkdocstrings"]._autorefs # noqa: WPS219,WPS437 for identifier in ids: From 78e11fa00d3ac29bf627aceee5e59a7e35f35172 Mon Sep 17 00:00:00 2001 From: johnthagen Date: Sun, 10 Apr 2022 08:05:30 -0400 Subject: [PATCH 03/15] docs: Fix Windows support in automatic code reference recipe Co-authored-by: Oleh Prypin Issue #418: https://github.com/mkdocstrings/mkdocstrings/issues/418 PR #419: https://github.com/mkdocstrings/mkdocstrings/pull/419 --- docs/recipes.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/recipes.md b/docs/recipes.md index d0f92d38..ff8100a2 100644 --- a/docs/recipes.md +++ b/docs/recipes.md @@ -179,7 +179,7 @@ for path in sorted(Path("src").rglob("*.py")): elif parts[-1] == "__main__": continue - nav[parts] = str(doc_path) # (1) + nav[parts] = doc_path.as_posix() # (1) with mkdocs_gen_files.open(full_doc_path, "w") as fd: ident = ".".join(parts) @@ -252,7 +252,7 @@ for path in sorted(Path("src").rglob("*.py")): elif parts[-1] == "__main__": continue - nav[parts] = str(doc_path) + nav[parts] = doc_path.as_posix() with mkdocs_gen_files.open(full_doc_path, "w") as fd: ident = ".".join(parts) @@ -260,8 +260,8 @@ for path in sorted(Path("src").rglob("*.py")): mkdocs_gen_files.set_edit_path(full_doc_path, path) -with mkdocs_gen_files.open("reference/SUMMARY.md", "w") as nav_file: # (2) - nav_file.writelines(nav.build_literate_nav()) # (3) +with mkdocs_gen_files.open("reference/SUMMARY.md", "w") as nav_file: + nav_file.writelines(nav.build_literate_nav()) ``` And update your MkDocs configuration to list the plugin: From c4c51cde8f706f184d5eef76084dc2447415ce7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Sun, 10 Apr 2022 14:31:44 +0200 Subject: [PATCH 04/15] chore: Add missing space in deprecation warning --- src/mkdocstrings/handlers/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mkdocstrings/handlers/base.py b/src/mkdocstrings/handlers/base.py index 3bdf2336..24eaa4d2 100644 --- a/src/mkdocstrings/handlers/base.py +++ b/src/mkdocstrings/handlers/base.py @@ -447,7 +447,7 @@ def __init__(self, *args: str | BaseCollector | BaseRenderer, **kwargs: str | Ba warnings.warn( DeprecationWarning( "The BaseRenderer class is deprecated, and passing an instance of it " - "to your handler is deprecated as well. Instead, define the `render` method" + "to your handler is deprecated as well. Instead, define the `render` method " "directly on your handler class (as well as other methods and attributes like " "`get_templates_dir`, `get_anchors`, `update_env` and `fallback_theme`, `extra_css`)." ) From 9055d582a6244a45a1af1aeccd8bf3436889a1a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Sun, 10 Apr 2022 14:33:03 +0200 Subject: [PATCH 05/15] build: Stop depending directly on mkdocstrings-python-legacy --- pyproject.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d2332e74..4d205cf1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,6 @@ dependencies = [ "MarkupSafe>=1.1", "mkdocs>=1.2", "mkdocs-autorefs>=0.3.1", - "mkdocstrings-python-legacy>=0.2", "pymdown-extensions>=6.3", ] @@ -99,8 +98,6 @@ quality = [ ] tests = [ "docutils", - # TODO: uncomment once the legacy handler is optional - # "mkdocstrings-python-legacy>=0.1", "pygments>=2.10", # python 3.6 "pytest>=6.2", "pytest-cov>=3.0", From 3335310b985401642fea8322aba503cafa1c50b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Wed, 20 Apr 2022 11:56:16 +0200 Subject: [PATCH 06/15] refactor: Deprecate 'selection' and 'rendering' YAML keys As seen in commit eb822cb, the separation of the selection/collection and rendering configuration is problematic. This commit further reduces this separation by merging the two current YAML keys 'selection' and 'rendering' into a single 'options' key. It means both the 'collect' and 'render' methods have access to every option. The old keys can still be used, but are deprecated, and therefore a deprecation warning is emitted if these keys are found in either global or local configurations. PR #420: https://github.com/mkdocstrings/mkdocstrings/pull/420 --- mkdocs.yml | 3 +-- src/mkdocstrings/extension.py | 17 +++++++++++++---- tests/test_extension.py | 12 ++++++++++++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index 572d771d..3a82fccf 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -91,11 +91,10 @@ plugins: - https://docs.python.org/3/objects.inv - https://docs.python-requests.org/en/master/objects.inv # demonstration purpose in the docs - https://mkdocstrings.github.io/autorefs/objects.inv - selection: + options: docstring_style: google docstring_options: ignore_init_summary: yes - rendering: merge_init_into_class: yes show_submodules: no watch: diff --git a/src/mkdocstrings/extension.py b/src/mkdocstrings/extension.py index 3b0e54fb..78d30165 100644 --- a/src/mkdocstrings/extension.py +++ b/src/mkdocstrings/extension.py @@ -24,6 +24,7 @@ import re from collections import ChainMap from typing import Any, Mapping, MutableMapping, MutableSequence, Tuple +from warnings import warn from xml.etree.ElementTree import Element import yaml @@ -173,13 +174,21 @@ def _process_block( handler_config = self._handlers.get_handler_config(handler_name) handler = self._handlers.get_handler(handler_name, handler_config) - selection, rendering = get_item_configs(handler_config, config) + options = ChainMap(config.get("options", {}), handler_config.get("options", {})) + if not options: + selection, rendering = get_item_configs(handler_config, config) + if selection or rendering: + warn( + "'selection' and 'rendering' are deprecated and merged into a single 'options' YAML key", + DeprecationWarning, + ) + options = ChainMap(*selection.maps, *rendering.maps) # type: ignore[attr-defined] if heading_level: - rendering = ChainMap(rendering, {"heading_level": heading_level}) # like setdefault + options = ChainMap(options, {"heading_level": heading_level}) # like setdefault log.debug("Collecting data") try: - data: CollectorItem = handler.collect(identifier, selection) + data: CollectorItem = handler.collect(identifier, options) except CollectionError as exception: log.error(str(exception)) if PluginError is SystemExit: # When MkDocs 1.2 is sufficiently common, this can be dropped. @@ -193,7 +202,7 @@ def _process_block( log.debug("Rendering templates") try: - rendered = handler.render(data, rendering) + rendered = handler.render(data, options) except TemplateNotFound as exc: theme_name = self._config["theme_name"] log.error( diff --git a/tests/test_extension.py b/tests/test_extension.py index 8039e240..df388723 100644 --- a/tests/test_extension.py +++ b/tests/test_extension.py @@ -135,3 +135,15 @@ def test_dont_register_every_identifier_as_anchor(plugin): for identifier in ids: assert identifier not in autorefs._url_map # noqa: WPS437 assert identifier not in autorefs._abs_url_map # noqa: WPS437 + + +def test_use_deprecated_yaml_keys(ext_markdown): + """Check that using the deprecated 'selection' and 'rendering' YAML keys emits a deprecation warning.""" + with pytest.warns(DeprecationWarning, match="single 'options' YAML key"): + assert "h1" not in ext_markdown.convert("::: tests.fixtures.headings\n rendering:\n heading_level: 2") + + +def test_use_new_options_yaml_key(ext_markdown): + """Check that using the new 'options' YAML key works as expected.""" + assert "h1" in ext_markdown.convert("::: tests.fixtures.headings\n options:\n heading_level: 1") + assert "h1" not in ext_markdown.convert("::: tests.fixtures.headings\n options:\n heading_level: 2") From cccebc40c0d51c23381d53432d9355fba9a290ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Mon, 25 Apr 2022 18:11:37 +0200 Subject: [PATCH 07/15] feat: Pass config file path to handlers This is to allow handlers to build potential paths (like Python search paths) relative to the MkDocs configuration file path instead of the current working directory. Without it, the build becomes dependent on the CWD, breaking the --config-file option. Issue #311: https://github.com/mkdocstrings/mkdocstrings/issues/311 PR #425: https://github.com/mkdocstrings/mkdocstrings/pull/425 --- src/mkdocstrings/handlers/base.py | 5 +++-- src/mkdocstrings/plugin.py | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mkdocstrings/handlers/base.py b/src/mkdocstrings/handlers/base.py index 24eaa4d2..a8de29ac 100644 --- a/src/mkdocstrings/handlers/base.py +++ b/src/mkdocstrings/handlers/base.py @@ -571,8 +571,9 @@ def get_handler(self, name: str, handler_config: Optional[dict] = None) -> BaseH ) ) self._handlers[name] = module.get_handler( - self._config["theme_name"], - self._config["mkdocstrings"]["custom_templates"], + theme=self._config["theme_name"], + custom_templates=self._config["mkdocstrings"]["custom_templates"], + config_file_path=self._config["config_file_path"], **handler_config, ) return self._handlers[name] diff --git a/src/mkdocstrings/plugin.py b/src/mkdocstrings/plugin.py index 4f2fdda6..fd47291a 100644 --- a/src/mkdocstrings/plugin.py +++ b/src/mkdocstrings/plugin.py @@ -166,6 +166,7 @@ def on_config(self, config: Config, **kwargs: Any) -> Config: # noqa: W0613 (un extension_config = { "site_name": config["site_name"], + "config_file_path": config["config_file_path"], "theme_name": theme_name, "mdx": config["markdown_extensions"], "mdx_configs": config["mdx_configs"], From 91f5f83408c7aab9124cc19fa47c940541d6f5ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Sat, 30 Apr 2022 12:54:48 +0200 Subject: [PATCH 08/15] refactor: Log relative template paths if possible, instead of absolute --- src/mkdocstrings/loggers.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/mkdocstrings/loggers.py b/src/mkdocstrings/loggers.py index e135d729..d2722616 100644 --- a/src/mkdocstrings/loggers.py +++ b/src/mkdocstrings/loggers.py @@ -1,8 +1,9 @@ """Logging functions.""" import logging +from contextlib import suppress from pathlib import Path -from typing import Any, Callable, MutableMapping, Optional, Tuple +from typing import Any, Callable, MutableMapping, Optional, Sequence, Tuple from jinja2.runtime import Context from mkdocs.utils import warning_filter @@ -12,7 +13,12 @@ except ImportError: # TODO: remove once Jinja2 < 3.1 is dropped from jinja2 import contextfunction as pass_context # noqa: WPS440 -TEMPLATES_DIR = Path(__file__).parent / "templates" +try: + import mkdocstrings_handlers +except ImportError: + TEMPLATES_DIRS: Sequence[Path] = () +else: + TEMPLATES_DIRS = tuple(mkdocstrings_handlers.__path__) # noqa: WPS609 class LoggerAdapter(logging.LoggerAdapter): @@ -105,10 +111,12 @@ def get_template_path(context: Context) -> str: context_name: str = str(context.name) filename = context.environment.get_template(context_name).filename if filename: - try: - return str(Path(filename).relative_to(TEMPLATES_DIR)) - except ValueError: - return filename + for template_dir in TEMPLATES_DIRS: + with suppress(ValueError): + return str(Path(filename).relative_to(template_dir)) + with suppress(ValueError): + return str(Path(filename).relative_to(Path.cwd())) + return filename return context_name From 5d3250f181eb74b3c00b18249869daf43d771a2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Fri, 6 May 2022 11:39:31 +0200 Subject: [PATCH 09/15] chore: Template upgrade --- .copier-answers.yml | 2 +- .github/workflows/ci.yml | 2 +- README.md | 24 ------------------------ pyproject.toml | 4 ++-- scripts/setup.sh | 7 ++++--- 5 files changed, 8 insertions(+), 31 deletions(-) diff --git a/.copier-answers.yml b/.copier-answers.yml index baffd05d..7dd4a454 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,5 +1,5 @@ # Changes here will be overwritten by Copier -_commit: 0.9.4 +_commit: 0.9.6 _src_path: gh:pawamoy/copier-pdm.git author_email: pawamoy@pm.me author_fullname: Timothée Mazzucotelli diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6e503af3..d9133186 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -104,7 +104,7 @@ jobs: key: tests-cache-${{ runner.os }}-${{ matrix.python-version }} - name: Install dependencies - run: pdm install -G duty -G tests -G docs + run: pdm install --no-editable -G duty -G tests -G docs - name: Run the test suite run: pdm run duty test diff --git a/README.md b/README.md index 16c46ff1..534c64bf 100644 --- a/README.md +++ b/README.md @@ -62,30 +62,6 @@ Come have a chat or ask questions on our [Gitter channel](https://gitter.im/mkdo - **Reasonable defaults:** you should be able to just drop the plugin in your configuration and enjoy your auto-generated docs. -## Requirements - -mkdocstrings requires Python 3.7 or above. - -
-To install Python 3.7, I recommend using pyenv. - -```bash -# install pyenv -git clone https://github.com/pyenv/pyenv ~/.pyenv - -# setup pyenv (you should also put these three lines in .bashrc or similar) -export PATH="${HOME}/.pyenv/bin:${PATH}" -export PYENV_ROOT="${HOME}/.pyenv" -eval "$(pyenv init -)" - -# install Python 3.7 -pyenv install 3.7.12 - -# make it available globally -pyenv global system 3.7.12 -``` -
- ## Installation With `pip`: diff --git a/pyproject.toml b/pyproject.toml index 4d205cf1..e29ef389 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -57,9 +57,10 @@ Funding = "https://github.com/sponsors/mkdocstrings" mkdocstrings = "mkdocstrings.plugin:MkdocstringsPlugin" [tool.pdm] +version = {use_scm = true} package-dir = "src" includes = ["src/mkdocstrings"] -version = {use_scm = true} +editable-backend = "editables" [tool.pdm.dev-dependencies] duty = ["duty>=0.7"] @@ -78,7 +79,6 @@ format = [ "isort>=5.10", ] maintain = [ - # TODO: remove this section when git-changelog is more powerful "git-changelog>=0.4", ] quality = [ diff --git a/scripts/setup.sh b/scripts/setup.sh index 62687701..188eaebc 100755 --- a/scripts/setup.sh +++ b/scripts/setup.sh @@ -21,9 +21,10 @@ restore_previous_python_version() { } if [ -n "${PYTHON_VERSIONS}" ]; then - old_python_version="$(pdm config python.path)" - echo "> Currently selected Python version: ${old_python_version##*/}" - trap "restore_previous_python_version ${old_python_version}" EXIT + if old_python_version="$(pdm config python.path 2>/dev/null)"; then + echo "> Currently selected Python version: ${old_python_version##*/}" + trap "restore_previous_python_version ${old_python_version}" EXIT + fi for python_version in ${PYTHON_VERSIONS}; do if pdm use -f "python${python_version}" &>/dev/null; then echo "> Using Python ${python_version} interpreter" From c20022e6adfd3a18fd698f50355dfce534b9feb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Sun, 8 May 2022 11:38:17 +0200 Subject: [PATCH 10/15] refactor: Deprecate watch feature in favor of MkDocs' built-in one --- src/mkdocstrings/plugin.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/mkdocstrings/plugin.py b/src/mkdocstrings/plugin.py index fd47291a..a9c8ece6 100644 --- a/src/mkdocstrings/plugin.py +++ b/src/mkdocstrings/plugin.py @@ -19,6 +19,7 @@ from concurrent import futures from typing import Any, BinaryIO, Callable, Iterable, List, Mapping, Optional, Tuple from urllib import request +from warnings import warn from mkdocs.config import Config from mkdocs.config.config_options import Type as MkType @@ -68,10 +69,11 @@ class MkdocstringsPlugin(BasePlugin): Available options are: - - __`watch`__: A list of directories to watch. Only used when serving the documentation with mkdocs. + - **`watch` (deprecated)**: A list of directories to watch. Only used when serving the documentation with mkdocs. Whenever a file changes in one of directories, the whole documentation is built again, and the browser refreshed. - - __`default_handler`__: The default handler to use. The value is the name of the handler module. Default is "python". - - __`handlers`__: Global configuration of handlers. You can set global configuration per handler, applied everywhere, + Deprecated in favor of the now built-in `watch` feature of MkDocs. + - **`default_handler`**: The default handler to use. The value is the name of the handler module. Default is "python". + - **`handlers`**: Global configuration of handlers. You can set global configuration per handler, applied everywhere, but overridable in each "autodoc" instruction. Example: ```yaml @@ -115,6 +117,7 @@ def handlers(self) -> Handlers: raise RuntimeError("The plugin hasn't been initialized with a config yet") return self._handlers + # TODO: remove once watch feature is removed def on_serve(self, server: LiveReloadServer, builder: Callable, **kwargs: Any): # noqa: W0613 (unused arguments) """Watch directories. @@ -128,9 +131,15 @@ def on_serve(self, server: LiveReloadServer, builder: Callable, **kwargs: Any): builder: The function to build the site. **kwargs: Additional arguments passed by MkDocs. """ - for element in self.config["watch"]: - log.debug(f"Adding directory '{element}' to watcher") - server.watch(element, builder) + if self.config["watch"]: + warn( + "mkdocstrings' watch feature is deprecated in favor of MkDocs' watch feature, " + "see https://www.mkdocs.org/user-guide/configuration/#watch.", + DeprecationWarning, + ) + for element in self.config["watch"]: + log.debug(f"Adding directory '{element}' to watcher") + server.watch(element, builder) def on_config(self, config: Config, **kwargs: Any) -> Config: # noqa: W0613 (unused arguments) """Instantiate our Markdown extension. From 7c71f2623b667d43c5e9eb8aea881df2c9984a0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Sun, 8 May 2022 11:39:12 +0200 Subject: [PATCH 11/15] refactor: Support options / deprecated options mix-up --- src/mkdocstrings/extension.py | 39 +++++++++++++---------------------- 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/src/mkdocstrings/extension.py b/src/mkdocstrings/extension.py index 78d30165..be0c48bb 100644 --- a/src/mkdocstrings/extension.py +++ b/src/mkdocstrings/extension.py @@ -23,7 +23,7 @@ """ import re from collections import ChainMap -from typing import Any, Mapping, MutableMapping, MutableSequence, Tuple +from typing import Any, MutableSequence, Tuple from warnings import warn from xml.etree.ElementTree import Element @@ -174,15 +174,19 @@ def _process_block( handler_config = self._handlers.get_handler_config(handler_name) handler = self._handlers.get_handler(handler_name, handler_config) - options = ChainMap(config.get("options", {}), handler_config.get("options", {})) - if not options: - selection, rendering = get_item_configs(handler_config, config) - if selection or rendering: - warn( - "'selection' and 'rendering' are deprecated and merged into a single 'options' YAML key", - DeprecationWarning, - ) - options = ChainMap(*selection.maps, *rendering.maps) # type: ignore[attr-defined] + global_options = handler_config.get("options", {}) + local_options = config.get("options", {}) + deprecated_global_options = ChainMap(handler_config.get("selection", {}), handler_config.get("rendering", {})) + deprecated_local_options = ChainMap(config.get("selection", {}), config.get("rendering", {})) + + options = ChainMap(local_options, deprecated_local_options, global_options, deprecated_global_options) + + if deprecated_global_options or deprecated_local_options: + warn( + "'selection' and 'rendering' are deprecated and merged into a single 'options' YAML key", + DeprecationWarning, + ) + if heading_level: options = ChainMap(options, {"heading_level": heading_level}) # like setdefault @@ -213,21 +217,6 @@ def _process_block( return rendered, handler, data -def get_item_configs(handler_config: dict, config: dict) -> Tuple[Mapping, MutableMapping]: - """Get the selection and rendering configuration merged into the global configuration of the given handler. - - Arguments: - handler_config: The global configuration of a handler. It can be an empty dictionary. - config: The configuration to merge into the global handler configuration. - - Returns: - Two dictionaries: selection and rendering. The local configurations are merged into the global ones. - """ - item_selection_config = ChainMap(config.get("selection", {}), handler_config.get("selection", {})) - item_rendering_config = ChainMap(config.get("rendering", {}), handler_config.get("rendering", {})) - return item_selection_config, item_rendering_config - - class _PostProcessor(Treeprocessor): def run(self, root: Element): carry_text = "" From aa77b9c5ae2a4f51335254cf4346f6ea5b0afe38 Mon Sep 17 00:00:00 2001 From: Oleh Prypin Date: Sun, 8 May 2022 15:27:05 +0200 Subject: [PATCH 12/15] docs: Add logo --- docs/css/style.css | 9 +++++++++ docs/logo.svg | 18 ++++++++++++++++++ mkdocs.yml | 3 +-- 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 docs/logo.svg diff --git a/docs/css/style.css b/docs/css/style.css index abd97598..91d10018 100644 --- a/docs/css/style.css +++ b/docs/css/style.css @@ -1,3 +1,12 @@ +/* Increase logo size */ +.md-header__button.md-logo { + padding-bottom: 0.2rem; + padding-right: 0; +} +.md-header__button.md-logo img { + height: 1.5rem; +} + /* Mark external links as such (also in nav) */ a.external:hover::after, a.md-nav__link[href^="https:"]:hover::after { /* https://primer.style/octicons/link-external-16 */ diff --git a/docs/logo.svg b/docs/logo.svg new file mode 100644 index 00000000..ce91662b --- /dev/null +++ b/docs/logo.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/mkdocs.yml b/mkdocs.yml index 3a82fccf..868a5f8f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -32,8 +32,7 @@ nav: theme: name: material - icon: - logo: material/currency-sign + logo: logo.svg features: - content.code.annotate - navigation.tabs From 624e7122dec09981efbfad8216e2657414451b1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Thu, 26 May 2022 18:40:01 +0200 Subject: [PATCH 13/15] docs: Update docs --- CONTRIBUTING.md | 29 +++--- docs/handlers/overview.md | 208 +++++++++++++++++-------------------- docs/recipes.md | 53 ++++------ docs/theming.md | 119 +++++++-------------- docs/troubleshooting.md | 39 +++---- docs/usage.md | 126 +++++++++++----------- mkdocs.yml | 4 +- pyproject.toml | 2 + src/mkdocstrings/plugin.py | 10 +- 9 files changed, 242 insertions(+), 348 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3af78086..7f80c98a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,21 +14,20 @@ cd mkdocstrings make setup ``` -!!! note - If it fails for some reason, - you'll need to install - [PDM](https://github.com/pdm-project/pdm) - manually. - - You can install it with: - - ```bash - python3 -m pip install --user pipx - pipx install pdm - ``` - - Now you can try running `make setup` again, - or simply `pdm install`. +> NOTE: If it fails for some reason, +> you'll need to install +> [PDM](https://github.com/pdm-project/pdm) +> manually. +> +> You can install it with: +> +> ```bash +> python3 -m pip install --user pipx +> pipx install pdm +> ``` +> +> Now you can try running `make setup` again, +> or simply `pdm install`. You now have the dependencies installed. diff --git a/docs/handlers/overview.md b/docs/handlers/overview.md index e7852e80..fd3e87bc 100644 --- a/docs/handlers/overview.md +++ b/docs/handlers/overview.md @@ -14,9 +14,8 @@ Since version 0.18, a new, experimental Python handler is available. It is based on [Griffe](https://github.com/mkdocstrings/griffe), which is an improved version of [pytkdocs](https://github.com/mkdocstrings/pytkdocs). -Note that the experimental handler does not yet offer the same features as the legacy one. -If you are making extensive use of the current (legacy) Python handler selection and rendering options, -you might want to wait a bit before trying the experimental handler. +Note that the experimental handler does not yet support third-party libraries +like Django, Marshmallow, Pydantic, etc. It is also not completely ready to handle dynamically built objects, like classes built with a call to `type(...)`. For most other cases, the experimental handler will work just fine. @@ -25,7 +24,7 @@ If you want to keep using the legacy handler as long as possible, you can depend on `mkdocstrings-python-legacy` directly, or specify the `python-legacy` extra when depending on *mkdocstrings*: -```toml +```toml title="pyproject.toml" # PEP 621 dependencies declaration # adapt to your dependencies manager [project] @@ -37,25 +36,13 @@ dependencies = [ The legacy handler will continue to "work" for many releases, as long as the new handler does not cover all previous use-cases. -Using the legacy handler will emit a `UserWarning` stating that users -should specify the `python-legacy` extra when depending on *mkdocstrings*. -The warning will be emitted even if you do specify the extra, as we have -no way to detect it. - -Warnings can be globally ignored by setting the -[`PYTHONWARNINGS` environment variable](https://docs.python.org/3/library/warnings.html#describing-warning-filters): - -```bash -PYTHONWARNINGS=ignore::UserWarning:mkdocstrings.handlers.python -``` - ### Migrate to the experimental Python handler To use the new, experimental Python handler, you can depend on `mkdocstrings-python` directly, or specify the `python` extra when depending on *mkdocstrings*: -```toml +```toml title="pyproject.toml" # PEP 621 dependencies declaration # adapt to your dependencies manager [project] @@ -66,100 +53,80 @@ dependencies = [ #### Handler options -- `setup_commands` is not yet implemented. But in most cases, you won't need it, +- `setup_commands` is not yet implemented. In most cases, you won't need it, since by default the new handler does not execute the code. #### Selection options -- `filters` is not yet implemented. *Every* declared object is picked up by default, - but only rendered if it has a docstring. Since code is not executed, - inherited attributes (like special methods and private members) are not picked up. -- `members` is not yet implemented. -- `inherited_members` is not yet implemented. -- `docstring_style` is implemented, and used as before, +WARNING: Since *mkdocstrings* 0.19, the YAML `selection` key is merged into the `options` key. + +- [x] `filters` is implemented, and used as before. +- [x] `members` is implemented, and used as before. +- [ ] `inherited_members` is not yet implemented. +- [x] `docstring_style` is implemented, and used as before, except for the `restructured-text` style which is renamed `sphinx`. Numpy-style is now built-in, so you can stop depending on `pytkdocs[numpy-style]` or `docstring_parser`. -- `docstring_options` is implemented, and used as before. - Refer to the [`griffe` documentation](https://mkdocstrings.github.io/griffe/docstrings/#parsing-options) for the updated list of supported docstring options. -- `new_path_syntax` is irrelevant now. If you were setting it to True, +- [x] `docstring_options` is implemented, and used as before. + Refer to the [`griffe` documentation](https://mkdocstrings.github.io/griffe/docstrings/#parsing-options) + for the updated list of supported docstring options. +- [x] `new_path_syntax` is irrelevant now. If you were setting it to True, remove the option and replace every colon (`:`) in your autodoc identifiers by dots (`.`). +See [all the handler's options](https://mkdocstrings.github.io/python/usage/). + #### Rendering options +WARNING: Since *mkdocstrings* 0.19, the YAML `rendering` key is merged into the `options` key. + Every previous option is supported. Additional options are available: -- `separate_signature`: Render the signature in a code block below the heading, +- `separate_signature`: Render the signature (or attribute value) in a code block below the heading, instead as inline code. Useful for long signatures. If Black is installed, - the signature is formatted. Default: false. -- `line_length`: The maximum line length to use when formatting signatures. Default: 60. + the signature is formatted. Default: `False`. +- `line_length`: The maximum line length to use when formatting signatures. Default: `60`. - `show_submodules`: Whether to render submodules of a module when iterating on children. - Default: true. + Default: `False`. - `docstring_section_style`: The style to use to render docstring sections such as attributes, parameters, etc. Available styles: `table` (default), `list` and `spacy`. The SpaCy style is a poor implementation of their [table style](https://spacy.io/api/doc/#init). We are open to improvements through PRs! +See [all the handler's options](https://mkdocstrings.github.io/python/usage/). + #### Templates Templates are mostly the same as before, but the file layout has changed, as well as some file names. Here is the new tree: ``` -theme -├── attribute.html -├── children.html -├── class.html -├── docstring -│   ├── admonition.html -│   ├── attributes.html -│   ├── examples.html -│   ├── other_parameters.html -│   ├── parameters.html -│   ├── raises.html -│   ├── receives.html -│   ├── returns.html -│   ├── warns.html -│   └── yields.html -├── docstring.html -├── expression.html -├── function.html -├── labels.html -├── module.html -└── signature.html -``` - -See them [in the handler repository](https://github.com/mkdocstrings/python/tree/8fc8ea5b112627958968823ef500cfa46b63613e/src/mkdocstrings_handlers/python/templates/material). - -In preparation for Jinja2 blocks, which will improve customization, -each one of these templates extends in fact a base version in `theme/_base`. Example: - -```html+jinja title="theme/docstring/admonition.html" -{% extends "_base/docstring/admonition.html" %} +📁 theme/ +├── 📄 attribute.html +├── 📄 children.html +├── 📄 class.html +├── 📁 docstring/ +│   ├── 📄 admonition.html +│   ├── 📄 attributes.html +│   ├── 📄 examples.html +│   ├── 📄 other_parameters.html +│   ├── 📄 parameters.html +│   ├── 📄 raises.html +│   ├── 📄 receives.html +│   ├── 📄 returns.html +│   ├── 📄 warns.html +│   └── 📄 yields.html +├── 📄 docstring.html +├── 📄 expression.html +├── 📄 function.html +├── 📄 labels.html +├── 📄 module.html +└── 📄 signature.html ``` -```html+jinja title="theme/_base/docstring/admonition.html" -{{ log.debug() }} -
- {{ section.title|convert_markdown(heading_level, html_id, strip_paragraph=True) }} - {{ section.value.contents|convert_markdown(heading_level, html_id) }} -
-``` - -It means you will be able to customize only *parts* of a template -without having to fully copy-paste it in your project: - -```jinja title="templates/theme/docstring.html" -{% extends "_base/docstring.html" %} -{% block contents %} - {{ block.super }} - Additional contents -{% endblock contents %} -``` - -**Block-level customization is not ready yet.** +See them [in the handler repository](https://github.com/mkdocstrings/python/tree/8fc8ea5b112627958968823ef500cfa46b63613e/src/mkdocstrings_handlers/python/templates/material). See the documentation about the Python handler templates: +https://mkdocstrings.github.io/python/customization/#templates. ## Custom handlers @@ -167,6 +134,13 @@ Since version 0.14, you can create and use custom handlers thanks to namespace packages. For more information about namespace packages, [see their documentation](https://packaging.python.org/guides/packaging-namespace-packages/). +TIP: **TL;DR - Project template for handlers.** +*mkdocstrings* provides a [Copier](https://github.com/copier-org/copier) template to kickstart +new handlers: https://github.com/mkdocstrings/handler-template. To use it, install Copier +(`pipx install copier`), then run `copier gh:mkdocstrings/handler-template my_handler` +to generate a new project. See [its upstream documentation](https://pawamoy.github.io/copier-pdm/) +to learn how to work on the generated project. + ### Packaging For *mkdocstrings*, a custom handler package would have the following structure: @@ -182,44 +156,51 @@ For *mkdocstrings*, a custom handler package would have the following structure: └─╴📄 __init__.py ``` -**Note the absence of `__init__.py` module in `mkdocstrings_handlers`!** +NOTE: **Note the absence of `__init__.py` module in `mkdocstrings_handlers`!** ### Code -A handler is composed of a Collector and a Renderer. +A handler is a subclass of the base handler provided by *mkdocstrings*. + +See the documentation for the [`BaseHandler`][mkdocstrings.handlers.base.BaseHandler]. +Subclasses of the base handler must implement the `collect` and `render` methods at least. +The `collect` method is responsible for collecting and returning data (extracting +documentation from source code, loading introspecting objects in memory, other sources? etc.) +while the `render` method is responsible for actually rendering the data to HTML, +using the Jinja templates provided by your package. -See the documentation for -[`BaseHandler`][mkdocstrings.handlers.base.BaseHandler], -[`BaseCollector`][mkdocstrings.handlers.base.BaseCollector] and -[`BaseRenderer`][mkdocstrings.handlers.base.BaseRenderer]. +You must implement a `get_handler` method at the module level. +This function takes the following parameters: + +- `theme` (string, theme name) +- `custom_templates` (optional string, path to custom templates directory) +- `config_file_path` (optional string, path to the config file) + +These arguments are all passed as keyword arguments, so you can ignore them +by adding `**kwargs` or similar to your signature. You can also accept +additional parameters: the handler's global-only options will be passed +to this function when instantiating your handler. Check out how the [Python handler](https://github.com/mkdocstrings/python/blob/master/src/mkdocstrings_handlers/python) is written for inspiration. -You must implement a `get_handler` method at the module level. -This function takes the `theme` (string, theme name) and -`custom_templates` (optional string, path to custom templates directory) -arguments, and you can add any other keyword argument you'd like. -The global configuration items (other than `selection` and `rendering`) -will be passed to this function when getting your handler. - ### Templates -Your renderer's implementation should normally be backed by templates, which go +Your handler's implementation should normally be backed by templates, which go to the directory `mkdocstrings_handlers/custom_handler/templates/some_theme`. (`custom_handler` here should be replaced with the actual name of your handler, and `some_theme` should be the name of an actual MkDocs theme that you support, e.g. `material`). With that structure, you can use `self.env.get_template("foo.html")` inside -your `render` implementation. This already chooses the subdirectory based on +your `render` method. This already chooses the subdirectory based on the current MkDocs theme. If you wish to support *any* MkDocs theme, rather than a few specifically selected ones, you can pick one theme's subdirectory to be the fallback for when an unknown theme is encountered. Then you just need to set the -`fallback_theme` variable on your renderer subclass. The fallback directory can +`fallback_theme` variable on your handler subclass. The fallback directory can be used even for themes you explicitly support: you can omit some template from one of the other theme directories in case they're exactly the same as in the fallback theme. @@ -231,15 +212,15 @@ Alternatively, you can put the CSS as a string into the `extra_css` variable of your renderer. Finally, it's possible to entirely omit templates, and tell *mkdocstrings* -to use the templates of another handler. In you renderer, override the +to use the templates of another handler. In you handler, override the `get_templates_dir()` method to return the other handlers templates path: ```python from pathlib import Path -from mkdocstrings.handlers.base import BaseRenderer +from mkdocstrings.handlers.base import BaseHandler -class CobraRenderer(BaseRenderer): +class CobraHandler(BaseHandler): def get_templates_dir(self, handler: str) -> Path: # use the python handler templates # (it assumes the python handler is installed) @@ -251,28 +232,25 @@ class CobraRenderer(BaseRenderer): When a custom handler is installed, it is then available to *mkdocstrings*. You can configure it as usual: -!!! example "mkdocs.yml" - ```yaml - plugins: - - mkdocstrings: - handlers: - custom_handler: - selection: - some_config_option: "a" - rendering: - other_config_option: 0 - handler_config_option: yes - ``` +```yaml title="mkdocs.yml" +plugins: +- mkdocstrings: + handlers: + custom_handler: + handler_config_option: yes + options: + some_config_option: "a" + other_config_option: 0 +``` ...and use it in your autodoc instructions: -```markdown +```md title="docs/some_page.md" # Documentation for an object ::: some.objects.path handler: custom_handler - selection: + options: some_config_option: "b" - rendering: other_config_option: 1 ``` diff --git a/docs/recipes.md b/docs/recipes.md index ff8100a2..5f006057 100644 --- a/docs/recipes.md +++ b/docs/recipes.md @@ -283,19 +283,6 @@ plugins: With this, `__init__` modules will be documented and bound to the sections themselves, better reflecting our public API. -!!! important - With the new Python handler, don't forget to hide submodules - when documenting a module, otherwise they will show up in sections: - - ```yaml title="mkdocs.yml" hl_lines="8" - plugins: - - mkdocstrings: - handlers: - python: - rendering: - show_submodules: no - ``` - ## Prevent selection of prompts and output in Python code blocks To prevent the selection of `>>>`, `...` and output in Python "Console" code blocks, @@ -321,26 +308,26 @@ extra_css: - css/code_select.css ``` -!!! warning - The `.highlight .gp, .highlight .go` CSS selector can have unintended side-effects. - To target `pycon` code blocks more specifically, you can configure the - `pymdownx.highlight` extension to use Pygments and set language classes - on code blocks: - - ```yaml title="mkdocs.yml" - markdown_extensions: - - pymdownx.highlight: - use_pygments: true - pygments_lang_class: true - ``` - - Then you can update the CSS selector like this: - - ```css title="docs/css/code_select.css" - .language-pycon .gp, .language-pycon .go { /* Generic.Prompt, Generic.Output */ - user-select: none; - } - ``` +> WARNING: +> The `.highlight .gp, .highlight .go` CSS selector can have unintended side-effects. +> To target `pycon` code blocks more specifically, you can configure the +> `pymdownx.highlight` extension to use Pygments and set language classes +> on code blocks: +> +> ```yaml title="mkdocs.yml" +> markdown_extensions: +> - pymdownx.highlight: +> use_pygments: true +> pygments_lang_class: true +> ``` +> +> Then you can update the CSS selector like this: +> +> ```css title="docs/css/code_select.css" +> .language-pycon .gp, .language-pycon .go { /* Generic.Prompt, Generic.Output */ +> user-select: none; +> } +> ``` If you don't want to enable this globally, you can still use `style` tags in the relevant pages, diff --git a/docs/theming.md b/docs/theming.md index 994d9ba6..73b7e0b3 100644 --- a/docs/theming.md +++ b/docs/theming.md @@ -3,10 +3,10 @@ *mkdocstrings* can support multiple MkDocs themes. It currently supports the *[Material for MkDocs](https://squidfunk.github.io/mkdocs-material/)* -theme and, partially, the built-in ReadTheDocs theme. +theme and, partially, the built-in MkDocs and ReadTheDocs themes. -Each renderer can fallback to a particular theme when the user selected theme is not supported. -For example, the Python renderer will fallback to the *Material for MkDocs* templates. +Each handler can fallback to a particular theme when the user selected theme is not supported. +For example, the Python handler will fallback to the *Material for MkDocs* templates. ## Customization @@ -21,59 +21,48 @@ To use custom templates and override the theme ones, specify the relative path to your templates directory with the `custom_templates` global configuration option: -!!! example "mkdocs.yml" - ```yaml - plugins: - - mkdocstrings: - custom_templates: templates - ``` +```yaml title="mkdocs.yml" +plugins: +- mkdocstrings: + custom_templates: templates +``` -You directory structure must be identical to the provided templates one: +Your directory structure must be identical to the provided templates one: ``` -templates -├─╴ -│ ├── -│ └── -└── - ├── - └── +📁 templates/ +├─╴📁 / +│ ├── 📁 / +│ └── 📁 / +└── 📁 / + ├── 📁 / + └── 📁 / ``` -(*[Check out the template tree on GitHub](https://github.com/mkdocstrings/mkdocstrings/tree/master/src/mkdocstrings/templates/)*) +For example, check out the Python +[template tree](https://github.com/mkdocstrings/python/tree/master/src/mkdocstrings_handlers/python/templates/) +on GitHub. You don't have to replicate the whole tree, only the handlers, themes or templates you want to override. For example, to override some templates of the *Material* theme for Python: ``` -templates -└── python - └── material - ├── parameters.html - └── exceptions.html +📁 templates/ +└── 📁 python/ + └── 📁 material/ + ├── 📄 parameters.html + └── 📄 exceptions.html ``` In the HTML files, replace the original contents with your modified version. In the future, the templates will use Jinja blocks, so it will be easier -to modify a small part of the template without copy-pasting the whole file. - -The *Material* theme provides the following template structure: - -- `children.html`: where the recursion happen, to render all children of an object - - `attribute.html`: to render attributes (class-attributes, etc.) - - `class.html`: to render classes - - `function.html`: to render functions - - `method.html`: to render methods - - `module.html`: to render modules -- `docstring.html`: to render docstrings - - `attributes.html`: to render attributes sections of docstrings - - `examples.html`: to render examples sections of docstrings - - `exceptions.html`: to render exceptions/"raises" sections of docstrings - - `parameters.html`: to render parameters/arguments sections of docstrings - - `return.html`: to render "return" sections of docstrings -- `properties.html`: to render the properties of an object (`staticmethod`, `read-only`, etc.) -- `signature.html`: to render functions and methods signatures +to modify small part of the templates without copy-pasting the whole files. + +See the documentation about templates for: + +- the Crystal handler: https://mkdocstrings.github.io/crystal/styling.html +- the Python handler: https://mkdocstrings.github.io/python/customization/#templates #### Debugging @@ -89,45 +78,11 @@ Every template has access to a `log` function, allowing to log messages as usual ### CSS classes -The *Material* theme uses the following CSS classes in the HTML: - -- `doc`: on all the following elements -- `doc-children`: on `div`s containing the children of an object -- `doc-object`: on `div`s containing an object - - `doc-attribute`: on `div`s containing an attribute - - `doc-class`: on `div`s containing a class - - `doc-function`: on `div`s containing a function - - `doc-method`: on `div`s containing a method - - `doc-module`: on `div`s containing a module -- `doc-heading`: on objects headings -- `doc-contents`: on `div`s wrapping the docstring then the children (if any) - - `first`: same, but only on the root object's contents `div` -- `doc-properties`: on `span`s wrapping the object's properties - - `doc-property`: on `small` elements containing a property - - `doc-property-PROPERTY`: same, where `PROPERTY` is replaced by the actual property - -!!! example "Example with colorful properties" - === "CSS" - ```css - .doc-property { border-radius: 15px; padding: 0 5px; } - .doc-property-special { background-color: blue; color: white; } - .doc-property-private { background-color: red; color: white; } - .doc-property-property { background-color: green; color: white; } - .doc-property-read-only { background-color: yellow; color: black; } - ``` - - === "Result" - -

- special - private - property - read-only -

- - As you can see, CSS is not my field of predilection... +Since each handler provides its own set of templates, with their own CSS classes, +we cannot list them all here. See the documentation about CSS classes for: + +- the Crystal handler: https://mkdocstrings.github.io/crystal/styling.html#custom-styles +- the Python handler: https://mkdocstrings.github.io/python/customization/#css-classes ### Syntax highlighting @@ -135,7 +90,7 @@ Code blocks that occur in the docstring of an item inserted with *mkdocstrings*, As for the CSS class used for code blocks -- it will also match the "normal" config, so the default (`.codehilite` or `.highlight`) will match your chosen Markdown extension for highlighting. -!!! important "Changed in version 0.15" - The CSS class used to always be `.highlight`, but now it depends on the configuration. +IMPORTANT: **Changed in version 0.15.** +The CSS class used to always be `.highlight`, but now it depends on the configuration. Long story short, you probably should add `pymdownx.highlight` to your `markdown_extensions`, and then use `.doc-contents .highlight` as the CSS selector in case you want to change something about *mkdocstrings'* code blocks specifically. diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 3cc3cfed..3f2243fd 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -14,12 +14,11 @@ Markdown extensions in `mkdocs.yml`. For example: ``` ``` -```yaml -# mkdocs.yml +```yaml title="mkdocs.yml" markdown_extensions: - - admonition - - codehilite - - pymdownx.superfences +- admonition +- codehilite +- pymdownx.superfences ``` ## Footnotes are duplicated or overridden @@ -48,10 +47,10 @@ when it should be `[Section][pytkdocs.parsers.docstrings.Section]`. ## Some objects are not rendered (they do not appear in the generated docs) -- Make sure the configuration options of the handler for both selection and rendering are correct. +- Make sure the configuration options of the handler are correct. Check the documentation for [Handlers](handlers/overview.md) to see the available options for each handler. - Also make sure your documentation in your source code is formatted correctly. -For Python code, check the [supported docstring styles](https://mkdocstrings.github.io/python/usage/#supported-docstrings-styles) page. + For Python code, check the [supported docstring styles](https://mkdocstrings.github.io/python/usage/#supported-docstrings-styles) page. - Re-run the Mkdocs command with `-v`, and carefully read any traceback. ## Tabs in docstrings (from `pymdownx.tabbed`) are not working properly @@ -115,23 +114,17 @@ use this workaround. ## The generated documentation does not look good -Are you using the Material theme? - -- "No": We do not support any other theme yet. - Check the [bugtracker][bugtracker] to see if there is a feature request - asking to support your theme. If you find one, vote with a thumbs up. If not, you can open a ticket. -- "Yes": Please open an ticket on the [bugtracker][bugtracker] with a detailed - explanation and screenshots of the bad-looking parts. - +Please open an ticket on the [bugtracker][bugtracker] with a detailed +explanation and screenshots of the bad-looking parts. Note that you can always [customize the look](theming.md) of *mkdocstrings* blocks -- through both HTML and CSS. ## Warning: could not find cross-reference target -!!! important "New in version 0.15" - Cross-linking used to include any Markdown heading, but now it's only for *mkdocstrings* identifiers by default. - See [Cross-references to any Markdown heading](usage.md#cross-references-to-any-markdown-heading) to opt back in. +TIP: **New in version 0.15.** +Cross-linking used to include any Markdown heading, but now it's only for *mkdocstrings* identifiers by default. +See [Cross-references to any Markdown heading](usage.md#cross-references-to-any-markdown-heading) to opt back in. -Make sure the referenced object was both collected and rendered: verify your selection and rendering options. +Make sure the referenced object is properly rendered: verify your configuration options. For false-positives, you can wrap the text in backticks (\`) to prevent `mkdocstrings` from trying to process it. @@ -170,10 +163,7 @@ def math_function(x, y): ### My docstrings in comments (`#:`) are not picked up -It's because [`pytkdocs`][pytkdocs] does not pick up documentation in comments. -To load documentation for modules, classes, methods and functions, it uses [`inspect`][inspect]. -To load documentation for attributes, it uses [`ast`][ast] to parse the source code, -searching for pairs of nodes like `assignment`-`string`, and [`ast`][ast] does not parse comments. +It's because we do not support type annotations in comments. So instead of: @@ -239,7 +229,4 @@ def my_function(*args, **kwargs): ``` [bugtracker]: https://github.com/mkdocstrings/mkdocstrings -[pytkdocs]: https://github.com/pawamoy/pytkdocs -[inspect]: https://docs.python.org/3/library/inspect.html -[ast]: https://docs.python.org/3/library/ast.html [markdown-katex]: https://gitlab.com/mbarkhau/markdown-katex diff --git a/docs/usage.md b/docs/usage.md index c965c984..49519cb8 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -11,13 +11,13 @@ The syntax is as follows: YAML block ``` -!!! note "Resources on YAML" - YAML can sometimes be a bit tricky, particularly on indentation. - Here are some resources that other users found useful to better - understand YAML's peculiarities. - - - [YAML idiosyncrasies](https://docs.saltproject.io/en/3000/topics/troubleshooting/yaml_idiosyncrasies.html) - - [YAML multiline](https://yaml-multiline.info/) +> NOTE: **Resources on YAML.** +> YAML can sometimes be a bit tricky, particularly on indentation. +> Here are some resources that other users found useful to better +> understand YAML's peculiarities. +> +> - [YAML idiosyncrasies](https://docs.saltproject.io/en/3000/topics/troubleshooting/yaml_idiosyncrasies.html) +> - [YAML multiline](https://yaml-multiline.info/) The `identifier` is a string identifying the object you want to document. The format of an identifier can vary from one handler to another. @@ -29,16 +29,10 @@ The YAML block is optional, and contains some configuration options: - `handler`: the name of the handler to use to collect and render this object. By default, it will use the value defined in the [Global options](#global-options)'s `default_handler` key, or `"python"`. -- `selection`: a dictionary of options passed to the handler's collector. - The collector is responsible for collecting the documentation from the source code. - Therefore, selection options change how the documentation is collected from the source code. -- `rendering`: a dictionary of options passed to the handler's renderer. - The renderer is responsible for rendering the documentation with Jinja2 templates. - Therefore, rendering options affect how the selected object's documentation is rendered. - -Every handler accepts at least these two keys, `selection` and `rendering`, -and some handlers accept additional keys. -Check the documentation for your handler of interest in [Handlers](handlers/overview.md). +- `options`: a dictionary of options passed to the handler's methods responsible both + for collecting and rendering the documentation. These options can be defined + globally (in `mkdocs.yml`, see [Global options](#global-options)), + locally (as described here), or both. !!! example "Example with the Python handler" === "docs/my_page.md" @@ -47,11 +41,10 @@ Check the documentation for your handler of interest in [Handlers](handlers/over ::: my_package.my_module.MyClass handler: python - selection: + options: members: - method_a - method_b - rendering: show_root_heading: false show_source: false ``` @@ -96,7 +89,7 @@ It is also possible to integrate a mkdocstrings identifier into a Markdown heade ```md ## ::: my_package.my_module.MyClass - rendering: + options: show_source: false ``` @@ -104,7 +97,7 @@ The above is equivalent to: ```md ::: my_package.my_module.MyClass - rendering: + options: show_source: false heading_level: 2 ``` @@ -113,8 +106,6 @@ The above is equivalent to: *mkdocstrings* accepts a few top-level configuration options in `mkdocs.yml`: -- `watch`: a list of directories to watch while serving the documentation. - See [Watch directories](#watch-directories). - `default_handler`: the handler that is used by default when no handler is specified. - `custom_templates`: the path to a directory containing custom templates. The path is relative to the docs directory. @@ -122,30 +113,32 @@ The above is equivalent to: - `handlers`: the handlers global configuration. - `enable_inventory`: whether to enable inventory file generation. See [Cross-references to other projects / inventories](#cross-references-to-other-projects-inventories) +- `watch` **(deprecated)**: a list of directories to watch while serving the documentation. + See [Watch directories](#watch-directories). **Deprecated in favor of the now built-in + [`watch` feature of MkDocs](https://www.mkdocs.org/user-guide/configuration/#watch). -Example: - -!!! example "mkdocs.yml" - ```yaml +!!! example + ```yaml title="mkdocs.yml" plugins: - mkdocstrings: + custom_templates: templates default_handler: python handlers: python: - rendering: + options: show_source: false - custom_templates: templates - watch: - - src/my_package ``` -The handlers global configuration can then be overridden by local configurations: + The handlers global configuration can then be overridden by local configurations: -```yaml -::: my_package.my_module.MyClass - rendering: - show_source: true -``` + ```yaml title="docs/some_page.md" + ::: my_package.my_module.MyClass + options: + show_source: true + ``` + +Some handlers accept additional global configuration. +Check the documentation for your handler of interest in [Handlers](handlers/overview.md). ## Cross-references @@ -182,26 +175,23 @@ is possible to link to with `[example][full.path.object1]`, regardless of the cu ### Cross-references to any Markdown heading -!!! important "Changed in version 0.15" - Linking to any Markdown heading used to be the default, but now opt-in is required. +TIP: **Changed in version 0.15.** +Linking to any Markdown heading used to be the default, but now opt-in is required. If you want to link to *any* Markdown heading, not just *mkdocstrings*-inserted items, please enable the [*autorefs* plugin for *MkDocs*](https://github.com/mkdocstrings/autorefs) by adding `autorefs` to `plugins`: -!!! example "mkdocs.yml" - ```yaml hl_lines="4" - plugins: - - admonition - - search - - autorefs - - mkdocstrings: - [...] - ``` +```yaml title="mkdocs.yml" hl_lines="3" +plugins: +- search +- autorefs +- mkdocstrings: + [...] +``` Note that you don't need to (`pip`) install anything more; this plugin is guaranteed to be pulled in with *mkdocstrings*. - !!! example === "doc1.md" ```md @@ -224,7 +214,7 @@ Note that you don't need to (`pip`) install anything more; this plugin is guaran ### Cross-references to a sub-heading in a docstring -!!! important "New in version 0.14" +TIP: **New in version 0.14.** If you have a Markdown heading *inside* your docstring, you can also link directly to it. In the example below you see the identifier to be linked is `foo.bar--tips`, because it's the "Tips" heading that's part of the `foo.bar` object, joined with "`--`". @@ -251,7 +241,7 @@ In the example below you see the identifier to be linked is `foo.bar--tips`, bec Check out the [tips][foo.bar--tips] ``` - === "Result HTML for doc2" + === "HTML result for doc2" ```html

Check out the tips

``` @@ -262,7 +252,7 @@ You may also notice that such a heading does not get rendered as a `

` elemen ### Cross-references to other projects / inventories -!!! tip "New in version 0.16." +TIP: **New in version 0.16.** Python developers coming from Sphinx might know about its `intersphinx` extension, that allows to cross-reference items between several projects. @@ -275,7 +265,7 @@ can load Sphinx-generated inventories (`objects.inv`). In the following snippet, we load the inventory provided by `requests`: -```yaml +```yaml title="mkdocs.yml" plugins: - mkdocstrings: handlers: @@ -342,25 +332,27 @@ plugins: ## Watch directories +DANGER: **Deprecated since version 0.19.** +Instead, use the built-in [`watch` feature of MkDocs](https://www.mkdocs.org/user-guide/configuration/#watch). + You can add directories to watch with the `watch` key. It accepts a list of paths. -!!! example "mkdocs.yml" - ```yaml - plugins: - - mkdocstrings: - watch: - - src/my_package_1 - - src/my_package_2 - ``` +```yaml title="mkdocs.yml" +plugins: + - mkdocstrings: + watch: + - src/my_package_1 + - src/my_package_2 +``` When serving your documentation and a change occur in one of the listed path, MkDocs will rebuild the site and reload the current page. -!!! note "The `watch` feature doesn't have special effects." - Adding directories to the `watch` list doesn't have any other effect than watching for changes. - For example, it will not tell the Python handler to look for packages in these paths - (the paths are not added to the `PYTHONPATH` variable). - If you want to tell Python where to look for packages and modules, - see [Python Handler: Finding modules](https://mkdocstrings.github.io/python/usage/#finding-modules). +NOTE: **The `watch` feature doesn't have special effects.** +Adding directories to the `watch` list doesn't have any other effect than watching for changes. +For example, it will not tell the Python handler to look for packages in these paths +(the paths are not added to the `PYTHONPATH` variable). +If you want to tell Python where to look for packages and modules, +see [Python Handler: Finding modules](https://mkdocstrings.github.io/python/usage/#finding-modules). diff --git a/mkdocs.yml b/mkdocs.yml index 868a5f8f..ad7997a1 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -5,6 +5,7 @@ repo_url: "https://github.com/mkdocstrings/mkdocstrings" edit_uri: "blob/master/docs/" repo_name: "mkdocstrings/mkdocstrings" site_dir: "site" +watch: [src/mkdocstrings] nav: - Home: @@ -60,6 +61,7 @@ extra_css: markdown_extensions: - admonition +- callouts - pymdownx.details - pymdownx.emoji - pymdownx.magiclink @@ -96,8 +98,6 @@ plugins: ignore_init_summary: yes merge_init_into_class: yes show_submodules: no - watch: - - src/mkdocstrings extra: social: diff --git a/pyproject.toml b/pyproject.toml index e29ef389..b4cbd1d1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -65,6 +65,8 @@ editable-backend = "editables" [tool.pdm.dev-dependencies] duty = ["duty>=0.7"] docs = [ + "markdown-callouts>=0.2.0", + "mkdocs>=1.3", # required for the watch feature "mkdocs-coverage>=0.2", "mkdocs-gen-files>=0.3", "mkdocs-literate-nav>=0.4", diff --git a/src/mkdocstrings/plugin.py b/src/mkdocstrings/plugin.py index a9c8ece6..34edcc06 100644 --- a/src/mkdocstrings/plugin.py +++ b/src/mkdocstrings/plugin.py @@ -81,17 +81,11 @@ class MkdocstringsPlugin(BasePlugin): - mkdocstrings: handlers: python: - selection: + options: selection_opt: true - rendering: rendering_opt: "value" - setup_commands: - - "import os" - - "import django" - - "os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'my_djang_app.settings')" - - "django.setup()" rust: - selection: + options: selection_opt: 2 ``` """ From 0a9daf28574ac667a2185801251129a54d9b41af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Sat, 28 May 2022 16:49:44 +0200 Subject: [PATCH 14/15] docs: Use installer instead of requests --- docs/usage.md | 19 ++++++++++--------- mkdocs.yml | 2 +- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index 49519cb8..02fc9091 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -263,7 +263,7 @@ to load the inventory it provides. Each handler will be responsible of loading inventories specific to its language. For example, the Python handler can load Sphinx-generated inventories (`objects.inv`). -In the following snippet, we load the inventory provided by `requests`: +In the following snippet, we load the inventory provided by `installer`: ```yaml title="mkdocs.yml" plugins: @@ -271,24 +271,24 @@ plugins: handlers: python: import: - - https://docs.python-requests.org/en/master/objects.inv + - https://installer.readthedocs.io/en/stable/objects.inv ``` -Now it is possible to cross-reference `requests`' items! For example: +Now it is possible to cross-reference `installer`'s items. For example: === "Markdown" ```md - See [requests.request][] to know what parameters you can pass. + See [installer.records][] to learn about records. ``` === "Result (HTML)" ```html -

See requests.request - to know what parameters you can pass.

+

See installer.records + to learn about records.

``` === "Result (displayed)" - See [requests.request][] to know what parameters you can pass. + See [installer.records][] to learn about records. You can of course select another version of the inventory, for example: @@ -298,7 +298,8 @@ plugins: handlers: python: import: - - https://docs.python-requests.org/en/v3.0.0/objects.inv + # latest instead of stable + - https://installer.readthedocs.io/en/latest/objects.inv ``` In case the inventory file is not served under the base documentation URL, @@ -319,7 +320,7 @@ on `https://docs.example.com/version/` instead of `https://cdn.example.com/versi Reciprocally, *mkdocstrings* also allows to *generate* an inventory file in the Sphinx format. It will be enabled by default if the Python handler is used, and generated as `objects.inv` in the final site directory. -Other projects will be able to cross-reference items from your project! +Other projects will be able to cross-reference items from your project. To explicitely enable or disable the generation of the inventory file, use the global `enable_inventory` option: diff --git a/mkdocs.yml b/mkdocs.yml index ad7997a1..d9c86361 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -90,7 +90,7 @@ plugins: python: import: - https://docs.python.org/3/objects.inv - - https://docs.python-requests.org/en/master/objects.inv # demonstration purpose in the docs + - https://installer.readthedocs.io/en/stable/objects.inv # demonstration purpose in the docs - https://mkdocstrings.github.io/autorefs/objects.inv options: docstring_style: google From 5c0e4d1290e4b54d3098281405b680291fc3639e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Sat, 28 May 2022 17:55:45 +0200 Subject: [PATCH 15/15] chore: Prepare release 0.19.0 --- CHANGELOG.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d40a65c8..5892de7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,46 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [0.19.0](https://github.com/mkdocstrings/mkdocstrings/releases/tag/0.19.0) - 2022-05-28 + +[Compare with 0.18.1](https://github.com/mkdocstrings/mkdocstrings/compare/0.18.1...0.19.0) + +### Highlights +We decided to deprecate a few things to pave the way towards a more +stable code base, bringing us closer to a v1. + +- Selection and rendering options are now combined into a single + `options` key. Using the old keys will emit a deprecation warning. +- The `BaseCollector` and `BaseRenderer` classes are deprecated in favor + of `BaseHandler`, which merges their functionality. Using the old + classes will emit a deprecation warning. + +New versions of the Python handler and the legacy Python handler +were also released in coordination with *mkdocstrings* 0.19. +See their respective changelogs: +[python](https://mkdocstrings.github.io/python/changelog/#070-2022-05-28), +[python-legacy](https://mkdocstrings.github.io/python-legacy/changelog/#023-2022-05-28). +Most notably, the Python handler gained the `members` and `filters` options +that prevented many users to switch to it. + +*mkdocstrings* stopped depending directly on the legacy Python handler. +It means you now have to explicitely depend on it, directly or through +the extra provided by *mkdocstrings*, if you want to continue using it. + +### Packaging / Dependencies +- Stop depending directly on mkdocstrings-python-legacy ([9055d58](https://github.com/mkdocstrings/mkdocstrings/commit/9055d582a6244a45a1af1aeccd8bf3436889a1a5) by Timothée Mazzucotelli). [Issue #376](https://github.com/mkdocstrings/mkdocstrings/issues/376) + +### Features +- Pass config file path to handlers ([cccebc4](https://github.com/mkdocstrings/mkdocstrings/commit/cccebc40c0d51c23381d53432d9355fba9a290ae) by Timothée Mazzucotelli). [Issue #311](https://github.com/mkdocstrings/mkdocstrings/issues/311), [PR #425](https://github.com/mkdocstrings/mkdocstrings/issues/425) + +### Code Refactoring +- Support options / deprecated options mix-up ([7c71f26](https://github.com/mkdocstrings/mkdocstrings/commit/7c71f2623b667d43c5e9eb8aea881df2c9984a0e) by Timothée Mazzucotelli). +- Deprecate watch feature in favor of MkDocs' built-in one ([c20022e](https://github.com/mkdocstrings/mkdocstrings/commit/c20022e6adfd3a18fd698f50355dfce534b9feb9) by Timothée Mazzucotelli). +- Log relative template paths if possible, instead of absolute ([91f5f83](https://github.com/mkdocstrings/mkdocstrings/commit/91f5f83408c7aab9124cc19fa47c940541d6f5ec) by Timothée Mazzucotelli). +- Deprecate `selection` and `rendering` YAML keys ([3335310](https://github.com/mkdocstrings/mkdocstrings/commit/3335310b985401642fea8322aba503cafa1c50b1) by Timothée Mazzucotelli). [PR #420](https://github.com/mkdocstrings/mkdocstrings/issues/420) +- Deprecate `BaseCollector` and `BaseRenderer` ([eb822cb](https://github.com/mkdocstrings/mkdocstrings/commit/eb822cb11ec065da0b1277299aae4ffeeffadc6f) by Timothée Mazzucotelli). [PR #413](https://github.com/mkdocstrings/mkdocstrings/issues/413) + + ## [0.18.1](https://github.com/mkdocstrings/mkdocstrings/releases/tag/0.18.1) - 2022-03-01 [Compare with 0.18.0](https://github.com/mkdocstrings/mkdocstrings/compare/0.18.0...0.18.1)