Apply rules to docstrings

This commit is contained in:
Oleh Prypin
2023-09-12 22:23:32 +02:00
parent 828f4685f2
commit 4710d73999
26 changed files with 121 additions and 166 deletions
+6 -8
View File
@@ -244,9 +244,7 @@ PKG_DIR = os.path.dirname(os.path.abspath(__file__))
@common_options
@color_option
def cli():
"""
MkDocs - Project documentation with Markdown.
"""
"""MkDocs - Project documentation with Markdown."""
@cli.command(name="serve")
@@ -263,7 +261,7 @@ def cli():
@common_config_options
@common_options
def serve_command(**kwargs):
"""Run the builtin development server"""
"""Run the builtin development server."""
from mkdocs.commands import serve
_enable_warnings()
@@ -276,7 +274,7 @@ def serve_command(**kwargs):
@click.option('-d', '--site-dir', type=click.Path(), help=site_dir_help)
@common_options
def build_command(clean, **kwargs):
"""Build the MkDocs documentation"""
"""Build the MkDocs documentation."""
from mkdocs.commands import build
_enable_warnings()
@@ -303,7 +301,7 @@ def build_command(clean, **kwargs):
def gh_deploy_command(
clean, message, remote_branch, remote_name, force, no_history, ignore_version, shell, **kwargs
):
"""Deploy your documentation to GitHub Pages"""
"""Deploy your documentation to GitHub Pages."""
from mkdocs.commands import build, gh_deploy
_enable_warnings()
@@ -334,7 +332,7 @@ def gh_deploy_command(
show_default=True,
)
def get_deps_command(config_file, projects_file):
"""Show required PyPI packages inferred from plugins in mkdocs.yml"""
"""Show required PyPI packages inferred from plugins in mkdocs.yml."""
from mkdocs.commands import get_deps
warning_counter = utils.CountHandler()
@@ -351,7 +349,7 @@ def get_deps_command(config_file, projects_file):
@click.argument("project_directory")
@common_options
def new_command(project_directory):
"""Create a new MkDocs project"""
"""Create a new MkDocs project."""
from mkdocs.commands import new
new.new(project_directory)
+2 -12
View File
@@ -35,9 +35,7 @@ def get_context(
page: Page | None = None,
base_url: str = '',
) -> templates.TemplateContext:
"""
Return the template context for a given page or template.
"""
"""Return the template context for a given page or template."""
if page is not None:
base_url = utils.get_relative_url('.', page.url)
@@ -65,9 +63,7 @@ def get_context(
def _build_template(
name: str, template: jinja2.Template, files: Files, config: MkDocsConfig, nav: Navigation
) -> str:
"""
Return rendered output for given template as a string.
"""
"""Return rendered output for given template as a string."""
# Run `pre_template` plugin events.
template = config.plugins.on_pre_template(template, template_name=name, config=config)
@@ -98,7 +94,6 @@ def _build_theme_template(
template_name: str, env: jinja2.Environment, files: Files, config: MkDocsConfig, nav: Navigation
) -> None:
"""Build a template using the theme environment."""
log.debug(f"Building theme template: {template_name}")
try:
@@ -128,7 +123,6 @@ def _build_theme_template(
def _build_extra_template(template_name: str, files: Files, config: MkDocsConfig, nav: Navigation):
"""Build user templates which are not part of the theme."""
log.debug(f"Building extra template: {template_name}")
file = files.get_file_from_path(template_name)
@@ -153,7 +147,6 @@ def _build_extra_template(template_name: str, files: Files, config: MkDocsConfig
def _populate_page(page: Page, config: MkDocsConfig, files: Files, dirty: bool = False) -> None:
"""Read page content from docs_dir and render Markdown."""
config._current_page = page
try:
# When --dirty is used, only read the page if the file has been modified since the
@@ -200,7 +193,6 @@ def _build_page(
excluded: bool = False,
) -> None:
"""Pass a Page to theme template and write output to site_dir."""
config._current_page = page
try:
# When --dirty is used, only build the page if the file has been modified since the
@@ -259,7 +251,6 @@ def build(
config: MkDocsConfig, live_server: LiveReloadServer | None = None, dirty: bool = False
) -> None:
"""Perform a full site build."""
logger = logging.getLogger('mkdocs')
# Add CountHandler for strict mode
@@ -374,5 +365,4 @@ def build(
def site_directory_contains_stale_files(site_directory: str) -> bool:
"""Check if the site directory contains stale files from a previous build."""
return bool(os.path.exists(site_directory) and os.listdir(site_directory))
+3 -2
View File
@@ -41,7 +41,8 @@ NotFound = ()
def dig(cfg, keys: str):
"""Receives a string such as 'foo.bar' and returns `cfg['foo']['bar']`, or `NotFound`.
"""
Receives a string such as 'foo.bar' and returns `cfg['foo']['bar']`, or `NotFound`.
A list of single-item dicts gets converted to a flat dict. This is intended for `plugins` config.
"""
@@ -90,7 +91,7 @@ def get_deps(projects_file_url: str, config_file_path: str | None = None) -> Non
"""
Print PyPI package dependencies inferred from a mkdocs.yml file based on a reverse mapping of known projects.
Parameters:
Args:
projects_file_url: URL or local path of the registry file that declares all known MkDocs-related projects.
The file is in YAML format and contains `projects: [{mkdocs_theme:, mkdocs_plugin:, markdown_extension:}]
config_file_path: Non-default path to mkdocs.yml.
+1 -1
View File
@@ -29,7 +29,7 @@ def serve(
**kwargs,
) -> None:
"""
Start the MkDocs development server
Start the MkDocs development server.
By default it will serve the documentation on http://localhost:8000/ and
it will rebuild the documentation and refresh the page automatically
+3 -8
View File
@@ -243,7 +243,6 @@ class Config(UserDict):
def load_dict(self, patch: dict) -> None:
"""Load config options from a dictionary."""
if not isinstance(patch, dict):
raise exceptions.ConfigurationError(
"The configuration is invalid. Expected a key-"
@@ -272,18 +271,14 @@ class Config(UserDict):
@functools.lru_cache(maxsize=None)
def get_schema(cls: type) -> PlainConfigSchema:
"""
Extract ConfigOptions defined in a class (used just as a container) and put them into a schema tuple.
"""
"""Extract ConfigOptions defined in a class (used just as a container) and put them into a schema tuple."""
if issubclass(cls, Config):
return cls._schema
return tuple((k, v) for k, v in cls.__dict__.items() if isinstance(v, BaseConfigOption))
class LegacyConfig(Config):
"""
A configuration object for plugins, as just a dict without type-safe attribute access.
"""
"""A configuration object for plugins, as just a dict without type-safe attribute access."""
def __init__(self, schema: PlainConfigSchema, config_file_path: str | None = None):
self._schema = tuple((k, v) for k, v in schema) # Re-create just for validation
@@ -345,7 +340,7 @@ def load_config(
config_file: str | IO | None = None, *, config_file_path: str | None = None, **kwargs
) -> MkDocsConfig:
"""
Load the configuration for a given file object or name
Load the configuration for a given file object or name.
The config_file can either be a file object, string or None. If it is None
the default `mkdocs.yml` filename will loaded.
+21 -20
View File
@@ -48,7 +48,7 @@ SomeConfig = TypeVar('SomeConfig', bound=Config)
class SubConfig(Generic[SomeConfig], BaseConfigOption[SomeConfig]):
"""
Subconfig Config Option
Subconfig Config Option.
New: If targeting MkDocs 1.4+, please pass a subclass of Config to the
constructor, instead of the old style of a sequence of ConfigOption instances.
@@ -93,7 +93,7 @@ class SubConfig(Generic[SomeConfig], BaseConfigOption[SomeConfig]):
self._do_validation = False if validate is None else validate
def __class_getitem__(cls, config_class: type[Config]):
"""Eliminates the need to write `config_class = FooConfig` when subclassing SubConfig[FooConfig]"""
"""Eliminates the need to write `config_class = FooConfig` when subclassing SubConfig[FooConfig]."""
name = f'{cls.__name__}[{config_class.__name__}]'
return type(name, (cls,), dict(config_class=config_class))
@@ -120,7 +120,8 @@ class SubConfig(Generic[SomeConfig], BaseConfigOption[SomeConfig]):
class PropagatingSubConfig(SubConfig[SomeConfig], Generic[SomeConfig]):
"""A SubConfig that must consist of SubConfigs with defined schemas.
"""
A SubConfig that must consist of SubConfigs with defined schemas.
Any value set on the top config gets moved to sub-configs with matching keys.
"""
@@ -318,7 +319,7 @@ class ConfigItems(ListOfItems[LegacyConfig]):
class Type(Generic[T], OptionallyRequired[T]):
"""
Type Config Option
Type Config Option.
Validate the type of a config option against a given Python type.
"""
@@ -352,7 +353,7 @@ class Type(Generic[T], OptionallyRequired[T]):
class Choice(Generic[T], OptionallyRequired[T]):
"""
Choice Config Option
Choice Config Option.
Validate the config option against a strict set of values.
"""
@@ -379,7 +380,7 @@ class Choice(Generic[T], OptionallyRequired[T]):
class Deprecated(BaseConfigOption):
"""
Deprecated Config Option
Deprecated Config Option.
Raises a warning as the option is deprecated. Uses `message` for the
warning. If `move_to` is set to the name of a new config option, the value
@@ -458,7 +459,7 @@ class _IpAddressValue(NamedTuple):
class IpAddress(OptionallyRequired[_IpAddressValue]):
"""
IpAddress Config Option
IpAddress Config Option.
Validate that an IP address is in an appropriate format
"""
@@ -497,7 +498,7 @@ class IpAddress(OptionallyRequired[_IpAddressValue]):
class URL(OptionallyRequired[str]):
"""
URL Config Option
URL Config Option.
Validate a URL by requiring a scheme is present.
"""
@@ -533,7 +534,8 @@ class URL(OptionallyRequired[str]):
class Optional(Generic[T], BaseConfigOption[Union[T, None]]):
"""Wraps a field and makes a None value possible for it when no value is set.
"""
Wraps a field and makes a None value possible for it when no value is set.
E.g. `my_field = config_options.Optional(config_options.Type(str))`
"""
@@ -692,9 +694,7 @@ class RepoName(Type[str]):
class FilesystemObject(Type[str]):
"""
Base class for options that point to filesystem objects.
"""
"""Base class for options that point to filesystem objects."""
existence_test: Callable[[str], bool] = staticmethod(os.path.exists)
name = 'file or directory'
@@ -720,7 +720,7 @@ class FilesystemObject(Type[str]):
class Dir(FilesystemObject):
"""
Dir Config Option
Dir Config Option.
Validate a path to a directory, optionally verifying that it exists.
"""
@@ -745,7 +745,7 @@ class DocsDir(Dir):
class File(FilesystemObject):
"""
File Config Option
File Config Option.
Validate a path to a file, optionally verifying that it exists.
"""
@@ -756,7 +756,7 @@ class File(FilesystemObject):
class ListOfPaths(ListOfItems[str]):
"""
List of Paths Config Option
List of Paths Config Option.
A list of file system paths. Raises an error if one of the paths does not exist.
@@ -780,7 +780,7 @@ class ListOfPaths(ListOfItems[str]):
class SiteDir(Dir):
"""
SiteDir Config Option
SiteDir Config Option.
Validates the site_dir and docs_dir directories do not contain each other.
"""
@@ -811,7 +811,7 @@ class SiteDir(Dir):
class Theme(BaseConfigOption[theme.Theme]):
"""
Theme Config Option
Theme Config Option.
Validate that the theme exists and build Theme instance.
"""
@@ -867,7 +867,7 @@ class Theme(BaseConfigOption[theme.Theme]):
class Nav(OptionallyRequired):
"""
Nav Config Option
Nav Config Option.
Validate the Nav config.
"""
@@ -961,14 +961,15 @@ class ExtraScript(BaseConfigOption[Union[ExtraScriptValue, str]]):
class MarkdownExtensions(OptionallyRequired[List[str]]):
"""
Markdown Extensions Config Option
Markdown Extensions Config Option.
A list or dict of extensions. Each list item may contain either a string or a one item dict.
A string must be a valid Markdown extension name with no config options defined. The key of
a dict item must be a valid Markdown extension name and the value must be a dict of config
options for that extension. Extension configs are set on the private setting passed to
`configkey`. The `builtins` keyword accepts a list of extensions which cannot be overridden by
the user. However, builtins can be duplicated to define config options for them if desired."""
the user. However, builtins can be duplicated to define config options for them if desired.
"""
def __init__(
self,
+4 -4
View File
@@ -62,7 +62,7 @@ class SearchPlugin(BasePlugin[_PluginConfig]):
"""Add a search feature to MkDocs."""
def on_config(self, config: MkDocsConfig, **kwargs) -> MkDocsConfig:
"Add plugin templates and scripts to config."
"""Add plugin templates and scripts to config."""
if config.theme.get('include_search_page'):
config.theme.static_templates.add('search.html')
if not config.theme.get('search_index_only'):
@@ -84,15 +84,15 @@ class SearchPlugin(BasePlugin[_PluginConfig]):
return config
def on_pre_build(self, config: MkDocsConfig, **kwargs) -> None:
"Create search index instance for later use."
"""Create search index instance for later use."""
self.search_index = SearchIndex(**self.config)
def on_page_context(self, context: TemplateContext, page: Page, **kwargs) -> None:
"Add page to search index."
"""Add page to search index."""
self.search_index.add_entry_from_context(page)
def on_post_build(self, config: MkDocsConfig, **kwargs) -> None:
"Build search index."
"""Build search index."""
output_base_path = os.path.join(config.site_dir, 'search')
search_index = self.search_index.generate_search_index()
json_output_path = os.path.join(output_base_path, 'search_index.json')
+4 -10
View File
@@ -46,9 +46,7 @@ class SearchIndex:
return None
def _add_entry(self, title: str | None, text: str, loc: str) -> None:
"""
A simple wrapper to add an entry, dropping bad characters.
"""
"""A simple wrapper to add an entry, dropping bad characters."""
text = text.replace('\u00a0', ' ')
text = re.sub(r'[ \t\n\r\f\v]+', ' ', text.strip())
@@ -86,7 +84,7 @@ class SearchIndex:
"""
Given a section on the page, the table of contents and
the absolute url for the page create an entry in the
index
index.
"""
toc_item = self._find_toc_by_id(toc, section.id)
@@ -95,7 +93,7 @@ class SearchIndex:
self._add_entry(title=toc_item.title, text=text, loc=abs_url + toc_item.url)
def generate_search_index(self) -> str:
"""python to json conversion"""
"""Python to json conversion."""
page_dicts = {'docs': self._entries, 'config': self.config}
data = json.dumps(page_dicts, sort_keys=True, separators=(',', ':'), default=str)
@@ -181,7 +179,6 @@ class ContentParser(HTMLParser):
def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None:
"""Called at the start of every HTML tag."""
# We only care about the opening tag for headings.
if tag not in _HEADER_TAGS:
return
@@ -198,7 +195,6 @@ class ContentParser(HTMLParser):
def handle_endtag(self, tag: str) -> None:
"""Called at the end of every HTML tag."""
# We only care about the opening tag for headings.
if tag not in _HEADER_TAGS:
return
@@ -206,9 +202,7 @@ class ContentParser(HTMLParser):
self.is_header_tag = False
def handle_data(self, data: str) -> None:
"""
Called for the text contents of each tag.
"""
"""Called for the text contents of each tag."""
self._stripped_html.append(data)
if self.section is None:
+17 -9
View File
@@ -4,12 +4,14 @@ from click import ClickException, echo
class MkDocsException(ClickException):
"""The base class which all MkDocs exceptions inherit from. This should
not be raised directly. One of the subclasses should be raised instead."""
"""
The base class which all MkDocs exceptions inherit from. This should
not be raised directly. One of the subclasses should be raised instead.
"""
class Abort(MkDocsException, SystemExit):
"""Abort the build"""
"""Abort the build."""
code = 1
@@ -18,16 +20,22 @@ class Abort(MkDocsException, SystemExit):
class ConfigurationError(MkDocsException):
"""This error is raised by configuration validation when a validation error
"""
This error is raised by configuration validation when a validation error
is encountered. This error should be raised by any configuration options
defined in a plugin's [config_scheme][]."""
defined in a plugin's [config_scheme][].
"""
class BuildError(MkDocsException):
"""This error may be raised by MkDocs during the build process. Plugins should
not raise this error."""
"""
This error may be raised by MkDocs during the build process. Plugins should
not raise this error.
"""
class PluginError(BuildError):
"""A subclass of [`mkdocs.exceptions.BuildError`][] which can be raised by plugin
events."""
"""
A subclass of [`mkdocs.exceptions.BuildError`][] which can be raised by plugin
events.
"""
+24 -27
View File
@@ -1,7 +1,4 @@
"""
Implements the plugin API for MkDocs.
"""
"""Implements the plugin API for MkDocs."""
from __future__ import annotations
import logging
@@ -38,7 +35,6 @@ log = logging.getLogger('mkdocs.plugins')
def get_plugins() -> dict[str, EntryPoint]:
"""Return a dict of all installed Plugins as {name: EntryPoint}."""
plugins = entry_points(group='mkdocs.plugins')
# Allow third-party plugins to override core plugins
@@ -70,7 +66,7 @@ class BasePlugin(Generic[SomeConfig]):
"""Set to true in subclasses to declare support for adding the same plugin multiple times."""
def __class_getitem__(cls, config_class: type[Config]):
"""Eliminates the need to write `config_class = FooConfig` when subclassing BasePlugin[FooConfig]"""
"""Eliminates the need to write `config_class = FooConfig` when subclassing BasePlugin[FooConfig]."""
name = f'{cls.__name__}[{config_class.__name__}]'
return type(name, (cls,), dict(config_class=config_class))
@@ -86,7 +82,6 @@ class BasePlugin(Generic[SomeConfig]):
self, options: dict[str, Any], config_file_path: str | None = None
) -> tuple[ConfigErrors, ConfigWarnings]:
"""Load config from a dict of options. Returns a tuple of (errors, warnings)."""
if self.config_class is LegacyConfig:
self.config = LegacyConfig(self.config_scheme, config_file_path=config_file_path) # type: ignore
else:
@@ -110,7 +105,7 @@ class BasePlugin(Generic[SomeConfig]):
Note that for initializing variables, the `__init__` method is still preferred.
For initializing per-build variables (and whenever in doubt), use the `on_config` event.
Parameters:
Args:
command: the command that MkDocs was invoked with, e.g. "serve" for `mkdocs serve`.
dirty: whether `--dirty` flag was passed.
"""
@@ -142,7 +137,7 @@ class BasePlugin(Generic[SomeConfig]):
it is activated. For example, additional files or directories could be added
to the list of "watched" files for auto-reloading.
Parameters:
Args:
server: `livereload.Server` instance
config: global configuration object
builder: a callable which gets passed to each call to `server.watch`
@@ -160,7 +155,7 @@ class BasePlugin(Generic[SomeConfig]):
after the user configuration is loaded and validated. Any alterations to the
config should be made here.
Parameters:
Args:
config: global configuration object
Returns:
@@ -173,7 +168,7 @@ class BasePlugin(Generic[SomeConfig]):
The `pre_build` event does not alter any variables. Use this event to call
pre-build scripts.
Parameters:
Args:
config: global configuration object
"""
@@ -185,7 +180,7 @@ class BasePlugin(Generic[SomeConfig]):
file objects in the collection. Use [Page Events](plugins.md#page-events) to manipulate page
specific data.
Parameters:
Args:
files: global files collection
config: global configuration object
@@ -199,7 +194,7 @@ class BasePlugin(Generic[SomeConfig]):
The `nav` event is called after the site navigation is created and can
be used to alter the site navigation.
Parameters:
Args:
nav: global navigation object
config: global configuration object
files: global files collection
@@ -217,7 +212,7 @@ class BasePlugin(Generic[SomeConfig]):
and can be used to alter the
[Jinja environment](https://jinja.palletsprojects.com/en/latest/api/#jinja2.Environment).
Parameters:
Args:
env: global Jinja environment
config: global configuration object
files: global files collection
@@ -232,7 +227,7 @@ class BasePlugin(Generic[SomeConfig]):
The `post_build` event does not alter any variables. Use this event to call
post-build scripts.
Parameters:
Args:
config: global configuration object
"""
@@ -244,7 +239,7 @@ class BasePlugin(Generic[SomeConfig]):
events which were scheduled to run after the error will have been skipped. See
[Handling Errors](plugins.md#handling-errors) for more details.
Parameters:
Args:
error: exception raised
"""
@@ -257,7 +252,7 @@ class BasePlugin(Generic[SomeConfig]):
The `pre_template` event is called immediately after the subject template is
loaded and can be used to alter the template.
Parameters:
Args:
template: a Jinja2 [Template](https://jinja.palletsprojects.com/en/latest/api/#jinja2.Template) object
template_name: string filename of template
config: global configuration object
@@ -275,7 +270,7 @@ class BasePlugin(Generic[SomeConfig]):
for the subject template and can be used to alter the context for that specific
template only.
Parameters:
Args:
context: dict of template context variables
template_name: string filename of template
config: global configuration object
@@ -294,7 +289,7 @@ class BasePlugin(Generic[SomeConfig]):
If an empty string is returned, the template is skipped and nothing is is
written to disc.
Parameters:
Args:
output_content: output of rendered template as string
template_name: string filename of template
config: global configuration object
@@ -311,7 +306,7 @@ class BasePlugin(Generic[SomeConfig]):
The `pre_page` event is called before any actions are taken on the subject
page and can be used to alter the `Page` instance.
Parameters:
Args:
page: `mkdocs.structure.pages.Page` instance
config: global configuration object
files: global files collection
@@ -326,7 +321,7 @@ class BasePlugin(Generic[SomeConfig]):
The `on_page_read_source` event can replace the default mechanism to read
the contents of a page's source from the filesystem.
Parameters:
Args:
page: `mkdocs.structure.pages.Page` instance
config: global configuration object
@@ -344,7 +339,7 @@ class BasePlugin(Generic[SomeConfig]):
from file and can be used to alter the Markdown source text. The meta-
data has been stripped off and is available as `page.meta` at this point.
Parameters:
Args:
markdown: Markdown source text of page as string
page: `mkdocs.structure.pages.Page` instance
config: global configuration object
@@ -363,7 +358,7 @@ class BasePlugin(Generic[SomeConfig]):
HTML (but before being passed to a template) and can be used to alter the
HTML body of the page.
Parameters:
Args:
html: HTML rendered from Markdown source as string
page: `mkdocs.structure.pages.Page` instance
config: global configuration object
@@ -381,7 +376,7 @@ class BasePlugin(Generic[SomeConfig]):
The `page_context` event is called after the context for a page is created
and can be used to alter the context for that specific page only.
Parameters:
Args:
context: dict of template context variables
page: `mkdocs.structure.pages.Page` instance
config: global configuration object
@@ -399,7 +394,7 @@ class BasePlugin(Generic[SomeConfig]):
page. If an empty string is returned, the page is skipped and nothing is
written to disc.
Parameters:
Args:
output: output of rendered template as string
page: `mkdocs.structure.pages.Page` instance
config: global configuration object
@@ -421,7 +416,8 @@ T = TypeVar('T')
def event_priority(priority: float) -> Callable[[T], T]:
"""A decorator to set an event priority for an event handler method.
"""
A decorator to set an event priority for an event handler method.
Recommended priority values:
`100` "first", `50` "early", `0` "default", `-50` "late", `-100` "last".
@@ -615,7 +611,8 @@ class PrefixedLogger(logging.LoggerAdapter):
def get_plugin_logger(name: str) -> PrefixedLogger:
"""Return a logger for plugins.
"""
Return a logger for plugins.
Arguments:
name: The name to use with `logging.getLogger`.
+4 -2
View File
@@ -79,8 +79,10 @@ class Files:
@property
def src_uris(self) -> dict[str, File]:
"""A mapping containing every file, with the keys being their
[`src_uri`][mkdocs.structure.files.File.src_uri]."""
"""
A mapping containing every file, with the keys being their
[`src_uri`][mkdocs.structure.files.File.src_uri].
"""
if self._src_uris is None:
self._src_uris = {file.src_uri: file for file in self._files}
return self._src_uris
+2 -4
View File
@@ -251,9 +251,7 @@ class Page(StructureItem):
return title
def render(self, config: MkDocsConfig, files: Files) -> None:
"""
Convert the Markdown source file to HTML as per the config.
"""
"""Convert the Markdown source file to HTML as per the config."""
if self.markdown is None:
raise RuntimeError("`markdown` field hasn't been set (via `read_source`)")
@@ -281,7 +279,7 @@ class _RelativePathTreeprocessor(markdown.treeprocessors.Treeprocessor):
def run(self, root: etree.Element) -> etree.Element:
"""
Update urls on anchors and images to make them relative
Update urls on anchors and images to make them relative.
Iterates through the full document tree looking for specific
tags and then makes them relative based on the site navigation
+2 -6
View File
@@ -32,9 +32,7 @@ def get_toc(toc_tokens: list[_TocToken]) -> TableOfContents:
class AnchorLink:
"""
A single entry in the table of contents.
"""
"""A single entry in the table of contents."""
def __init__(self, title: str, id: str, level: int) -> None:
self.title, self.id, self.level = title, id, level
@@ -66,9 +64,7 @@ class AnchorLink:
class TableOfContents(Iterable[AnchorLink]):
"""
Represents the table of contents for a given page.
"""
"""Represents the table of contents for a given page."""
def __init__(self, items: list[AnchorLink]) -> None:
self.items = items
-1
View File
@@ -29,7 +29,6 @@ if TYPE_CHECKING:
def build_page(title, path, config, md_src=''):
"""Helper which returns a Page object."""
files = Files([File(path, config.docs_dir, config.site_dir, config.use_directory_urls)])
page = Page(title, list(files)[0], config)
# Fake page.read_source()
+5 -15
View File
@@ -56,9 +56,7 @@ class ConfigBaseTests(unittest.TestCase):
@tempdir()
def test_load_default_file(self, temp_dir):
"""
test that `mkdocs.yml` will be loaded when '--config' is not set.
"""
"""Test that `mkdocs.yml` will be loaded when '--config' is not set."""
with open(os.path.join(temp_dir, 'mkdocs.yml'), 'w') as config_file:
config_file.write("site_name: MkDocs Test\n")
os.mkdir(os.path.join(temp_dir, 'docs'))
@@ -69,9 +67,7 @@ class ConfigBaseTests(unittest.TestCase):
@tempdir
def test_load_default_file_with_yaml(self, temp_dir):
"""
test that `mkdocs.yml` will be loaded when '--config' is not set.
"""
"""Test that `mkdocs.yml` will be loaded when '--config' is not set."""
with open(os.path.join(temp_dir, 'mkdocs.yaml'), 'w') as config_file:
config_file.write("site_name: MkDocs Test\n")
os.mkdir(os.path.join(temp_dir, 'docs'))
@@ -82,9 +78,7 @@ class ConfigBaseTests(unittest.TestCase):
@tempdir()
def test_load_default_file_prefer_yml(self, temp_dir):
"""
test that `mkdocs.yml` will be loaded when '--config' is not set.
"""
"""Test that `mkdocs.yml` will be loaded when '--config' is not set."""
with open(os.path.join(temp_dir, 'mkdocs.yml'), 'w') as config_file1:
config_file1.write("site_name: MkDocs Test1\n")
with open(os.path.join(temp_dir, 'mkdocs.yaml'), 'w') as config_file2:
@@ -104,9 +98,7 @@ class ConfigBaseTests(unittest.TestCase):
@tempdir()
def test_load_from_open_file(self, temp_path):
"""
`load_config` can accept an open file descriptor.
"""
"""`load_config` can accept an open file descriptor."""
config_fname = os.path.join(temp_path, 'mkdocs.yml')
config_file = open(config_fname, 'w+')
config_file.write("site_name: MkDocs Test\n")
@@ -135,9 +127,7 @@ class ConfigBaseTests(unittest.TestCase):
@tempdir
def test_load_missing_required(self, temp_dir):
"""
`site_name` is a required setting.
"""
"""`site_name` is a required setting."""
with open(os.path.join(temp_dir, 'mkdocs.yml'), 'w') as config_file:
config_file.write("site_dir: output\nsite_url: https://www.mkdocs.org\n")
os.mkdir(os.path.join(temp_dir, 'docs'))
@@ -901,7 +901,6 @@ class SiteDirTest(TestCase):
def test_common_prefix(self):
"""Legitimate settings with common prefixes should not fail validation."""
test_configs = (
{'docs_dir': 'docs', 'site_dir': 'docs-site'},
{'docs_dir': 'site-docs', 'site_dir': 'site'},
@@ -1200,7 +1199,7 @@ class SubConfigTest(TestCase):
self.get_config(Schema, {'option': val})
def test_subconfig_ignored(self):
"""Default behaviour of subconfig: validation is ignored"""
"""Default behaviour of subconfig: validation is ignored."""
# Nominal
class Schema1:
@@ -1263,8 +1262,7 @@ class SubConfigTest(TestCase):
self.assertEqual(conf['option'], {'cc': 'foo'})
def test_config_file_path_pass_through(self):
"""Necessary to ensure FilesystemObject validates the correct path"""
"""Necessary to ensure FilesystemObject validates the correct path."""
passed_config_path = None
class SubType(c.BaseConfigOption):
+1 -3
View File
@@ -1114,7 +1114,6 @@ class SiteDirTest(TestCase):
def test_common_prefix(self) -> None:
"""Legitimate settings with common prefixes should not fail validation."""
test_configs = (
{'docs_dir': 'docs', 'site_dir': 'docs-site'},
{'docs_dir': 'site-docs', 'site_dir': 'site'},
@@ -1556,8 +1555,7 @@ class SubConfigTest(TestCase):
conf = self.get_config(Schema, {'sub': None})
def test_config_file_path_pass_through(self) -> None:
"""Necessary to ensure FilesystemObject validates the correct path"""
"""Necessary to ensure FilesystemObject validates the correct path."""
passed_config_path = None
class SubType(c.BaseConfigOption):
+1 -1
View File
@@ -1,5 +1,5 @@
"""
# MkDocs Integration tests
# MkDocs Integration tests.
This is a simple integration test that builds the MkDocs
documentation against all of the builtin themes.
+4 -4
View File
@@ -30,19 +30,19 @@ class _DummyPluginConfig(base.Config):
class DummyPlugin(plugins.BasePlugin[_DummyPluginConfig]):
def on_page_content(self, html, **kwargs) -> str:
"""modify page content by prepending `foo` config value."""
"""Modify page content by prepending `foo` config value."""
return f'{self.config.foo} {html}'
def on_nav(self, nav, **kwargs) -> None:
"""do nothing (return None) to not modify item."""
"""Do nothing (return None) to not modify item."""
return None
def on_page_read_source(self, **kwargs) -> str:
"""create new source by prepending `foo` config value to 'source'."""
"""Create new source by prepending `foo` config value to 'source'."""
return f'{self.config.foo} source'
def on_pre_build(self, **kwargs) -> None:
"""do nothing (return None)."""
"""Do nothing (return None)."""
return None
+1 -3
View File
@@ -314,9 +314,7 @@ class SearchIndexTests(unittest.TestCase):
self.assertEqual(parser.data, [])
def test_find_toc_by_id(self):
"""
Test finding the relevant TOC item by the tag ID.
"""
"""Test finding the relevant TOC item by the tag ID."""
index = search_index.SearchIndex()
md = dedent(
+1 -1
View File
@@ -1109,7 +1109,7 @@ class RelativePathExtensionTests(unittest.TestCase):
def test_possible_target_uris(self):
def test(paths, expected='', exp_true=None, exp_false=None):
"""Test that `possible_target_uris` yields expected values, for use_directory_urls = true and false"""
"""Test that `possible_target_uris` yields expected values, for use_directory_urls = true and false."""
for use_directory_urls, expected_paths in (
(True, exp_true or expected),
(False, exp_false or expected),
+1 -3
View File
@@ -18,7 +18,7 @@ class Theme(MutableMapping[str, Any]):
"""
A Theme object.
Parameters:
Args:
name: The name of the theme as defined by its entrypoint.
custom_dir: User defined directory for custom templates.
static_templates: A list of templates to render as static pages.
@@ -117,7 +117,6 @@ class Theme(MutableMapping[str, Any]):
def _load_theme_config(self, name: str) -> None:
"""Recursively load theme and any parent themes."""
theme_dir = utils.get_theme_dir(name)
self.dirs.append(theme_dir)
@@ -149,7 +148,6 @@ class Theme(MutableMapping[str, Any]):
def get_env(self) -> jinja2.Environment:
"""Return a Jinja environment for the theme."""
loader = jinja2.FileSystemLoader(self.dirs)
# No autoreload because editing a template in the middle of a build is not useful.
env = jinja2.Environment(loader=loader, auto_reload=False)
+4 -13
View File
@@ -93,7 +93,7 @@ else:
def reduce_list(data_set: Iterable[T]) -> list[T]:
"""Reduce duplicate items in a list and preserve order"""
"""Reduce duplicate items in a list and preserve order."""
return list(dict.fromkeys(data_set))
@@ -123,9 +123,7 @@ def copy_file(source_path: str, output_path: str) -> None:
def write_file(content: bytes, output_path: str) -> None:
"""
Write content to output_path, making sure any parent directories exist.
"""
"""Write content to output_path, making sure any parent directories exist."""
output_dir = os.path.dirname(output_path)
os.makedirs(output_dir, exist_ok=True)
with open(output_path, 'wb') as f:
@@ -133,9 +131,7 @@ def write_file(content: bytes, output_path: str) -> None:
def clean_directory(directory: str) -> None:
"""
Remove the content of a directory recursively but not the directory itself.
"""
"""Remove the content of a directory recursively but not the directory itself."""
if not os.path.exists(directory):
return
@@ -165,9 +161,7 @@ _ERROR_TEMPLATE_RE = re.compile(r'^\d{3}\.html?$')
def is_error_template(path: str) -> bool:
"""
Return True if the given file path is an HTTP error template.
"""
"""Return True if the given file path is an HTTP error template."""
return bool(_ERROR_TEMPLATE_RE.match(path))
@@ -260,14 +254,12 @@ def path_to_url(path):
def get_theme_dir(name: str) -> str:
"""Return the directory of an installed theme by name."""
theme = get_themes()[name]
return os.path.dirname(os.path.abspath(theme.load().__file__))
def get_themes() -> dict[str, EntryPoint]:
"""Return a dict of all installed themes as {name: EntryPoint}."""
themes: dict[str, EntryPoint] = {}
eps: dict[EntryPoint, None] = dict.fromkeys(entry_points(group='mkdocs.themes'))
builtins = {ep.name for ep in eps if ep.dist is not None and ep.dist.name == 'mkdocs'}
@@ -295,7 +287,6 @@ def get_themes() -> dict[str, EntryPoint]:
def get_theme_names() -> Collection[str]:
"""Return a list of all installed themes by name."""
return get_themes().keys()
+1 -2
View File
@@ -23,12 +23,11 @@ def download_and_cache_url(
For tracking the age of the content, a prefix is inserted into the stored file, rather than relying on mtime.
Parameters:
Args:
url: URL or local path of the file to use.
cache_duration: how long to consider the URL content cached.
comment: The appropriate comment prefix for this file format.
"""
if urllib.parse.urlsplit(url).scheme not in ('http', 'https'):
with open(url, 'rb') as f:
return f.read()
+6 -3
View File
@@ -57,7 +57,8 @@ class _DirPlaceholder(os.PathLike):
class ConfigDirPlaceholder(_DirPlaceholder):
"""A placeholder object that gets resolved to the directory of the config file when used as a path.
"""
A placeholder object that gets resolved to the directory of the config file when used as a path.
The suffix can be an additional sub-path that is always appended to this path.
@@ -69,7 +70,8 @@ class ConfigDirPlaceholder(_DirPlaceholder):
class DocsDirPlaceholder(_DirPlaceholder):
"""A placeholder object that gets resolved to the docs dir when used as a path.
"""
A placeholder object that gets resolved to the docs dir when used as a path.
The suffix can be an additional sub-path that is always appended to this path.
@@ -81,7 +83,8 @@ class DocsDirPlaceholder(_DirPlaceholder):
class RelativeDirPlaceholder(_DirPlaceholder):
"""A placeholder object that gets resolved to the directory of the Markdown file currently being rendered.
"""
A placeholder object that gets resolved to the directory of the Markdown file currently being rendered.
This is the implementation of the `!relative` tag, but can also be passed programmatically.
"""
+1
View File
@@ -222,6 +222,7 @@ select = [
"F", "W", "E", "UP", "YTT", "C4", "FA", "PIE", "T20", "RSE", "TCH", "DTZ",
"B002", "B003", "B005", "B007", "B009", "B012", "B013", "B014", "B015", "B018", "B020", "B021", "B023", "B026", "B033", "B034", "B905",
"COM818",
"D200", "D201", "D202", "D204", "D207", "D208", "D209", "D210", "D211", "D213", "D214", "D300", "D301", "D400", "D402", "D403", "D405", "D412", "D414", "D415", "D416", "D417", "D419",
"PERF101",
"PGH002", "PGH004", "PGH005",
"PLE", "PLW0120", "PLW0127",