Fix overzealous validation of !relative tag (#3466)

If a Markdown extension immediately resolves the path inside its initialization (rather than just storing it for later as I was hoping) then it was failing the initial validation run that MkDocs does without populating an actual page yet.
This commit is contained in:
Oleh Prypin
2023-11-14 18:35:30 +01:00
committed by GitHub
parent dc45916aa1
commit 8aafea1742
3 changed files with 12 additions and 3 deletions

View File

@@ -10,6 +10,7 @@ import traceback
import types
import warnings
from collections import Counter, UserString
from types import SimpleNamespace
from typing import (
Any,
Callable,
@@ -993,6 +994,12 @@ class MarkdownExtensions(OptionallyRequired[List[str]]):
raise ValidationError(f"Invalid config options for Markdown Extension '{ext}'.")
self.configdata[ext] = cfg
def pre_validation(self, config, key_name):
# To appease validation in case it involves the `!relative` tag.
config._current_page = current_page = SimpleNamespace() # type: ignore[attr-defined]
current_page.file = SimpleNamespace()
current_page.file.src_path = ''
def run_validation(self, value: object) -> list[str]:
self.configdata: dict[str, dict] = {}
if not isinstance(value, (list, tuple, dict)):
@@ -1037,6 +1044,7 @@ class MarkdownExtensions(OptionallyRequired[List[str]]):
return extensions
def post_validation(self, config: Config, key_name: str):
config._current_page = None # type: ignore[attr-defined]
config[self.configkey] = self.configdata

View File

@@ -814,7 +814,7 @@ class _TestPreprocessor(markdown.preprocessors.Preprocessor):
class _TestExtension(markdown.extensions.Extension):
def __init__(self, base_path: str) -> None:
self.base_path = base_path
self.base_path = str(base_path)
def extendMarkdown(self, md: markdown.Markdown) -> None:
md.preprocessors.register(_TestPreprocessor(self.base_path), "mkdocs_test", priority=32)

View File

@@ -97,12 +97,13 @@ class RelativeDirPlaceholder(_DirPlaceholder):
super().__init__(config, suffix)
def value(self) -> str:
if self.config._current_page is None:
current_page = self.config._current_page
if current_page is None:
raise exceptions.ConfigurationError(
"The current file is not set for the '!relative' tag. "
"It cannot be used in this context; the intended usage is within `markdown_extensions`."
)
return os.path.dirname(self.config._current_page.file.abs_src_path)
return os.path.dirname(os.path.join(self.config.docs_dir, current_page.file.src_path))
def get_yaml_loader(loader=yaml.Loader, config: MkDocsConfig | None = None):