-
Notifications
You must be signed in to change notification settings - Fork 12
Adds pytest_markdown_docs_markdown_it for custom markdownit parser #47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,4 +29,5 @@ dev-dependencies = [ | |
| "pre-commit>=3.5.0", | ||
| "pytest~=8.1.0", | ||
| "ruff~=0.9.10", | ||
| "mdit-py-plugins~=0.4.2" | ||
| ] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,12 @@ | ||
| import typing | ||
|
|
||
| if typing.TYPE_CHECKING: | ||
| from markdown_it import MarkdownIt | ||
|
|
||
|
|
||
| def pytest_markdown_docs_globals() -> typing.Dict[str, typing.Any]: | ||
| return {} | ||
|
|
||
|
|
||
| def pytest_markdown_docs_markdown_it() -> "MarkdownIt": | ||
| """Configure a custom markdown_it.MarkdownIt parser.""" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,6 +24,7 @@ | |
|
|
||
| if typing.TYPE_CHECKING: | ||
| from markdown_it.token import Token | ||
| from markdown_it import MarkdownIt | ||
|
|
||
| logger = logging.getLogger("pytest-markdown-docs") | ||
|
|
||
|
|
@@ -123,15 +124,20 @@ def get_prefixed_strings( | |
|
|
||
|
|
||
| def extract_fence_tests( | ||
| markdown_it_parsers: typing.List["MarkdownIt"], | ||
| markdown_string: str, | ||
| start_line_offset: int, | ||
| source_path: pathlib.Path, | ||
| markdown_type: str = "md", | ||
| fence_syntax: FenceSyntax = FenceSyntax.default, | ||
| ) -> typing.Generator[FenceTestDefinition, None, None]: | ||
| import markdown_it | ||
| if not markdown_it_parsers: | ||
| from markdown_it import MarkdownIt | ||
|
|
||
| mi = MarkdownIt(config="commonmark") | ||
| else: | ||
| mi = markdown_it_parsers[0] | ||
|
|
||
| mi = markdown_it.MarkdownIt(config="commonmark") | ||
| tokens = mi.parse(markdown_string) | ||
|
|
||
| prev = "" | ||
|
|
@@ -294,8 +300,13 @@ def find_object_tests_recursive( | |
| or "<Unnamed obj>" | ||
| ) | ||
| fence_syntax = FenceSyntax(self.config.option.markdowndocs_syntax) | ||
| markdown_it_parsers = ( | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Regarding the list comment above - maybe it's better to validate the hook return value here (making sure it's at most one specification, since that's what we support) and then just pass in the single MarkdownIt we want to use?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With the other changes I don't think we need to check for anything here 👍 |
||
| self.config.hook.pytest_markdown_docs_markdown_it() | ||
| ) | ||
|
|
||
| for i, fence_test in enumerate( | ||
| extract_fence_tests( | ||
| markdown_it_parsers, | ||
| docstr, | ||
| docstring_offset, | ||
| source_path=self.path, | ||
|
|
@@ -317,8 +328,11 @@ def collect(self): | |
| markdown_content = self.path.read_text("utf8") | ||
| fence_syntax = FenceSyntax(self.config.option.markdowndocs_syntax) | ||
|
|
||
| markdown_it_parsers = self.config.hook.pytest_markdown_docs_markdown_it() | ||
|
|
||
| for i, fence_test in enumerate( | ||
| extract_fence_tests( | ||
| markdown_it_parsers, | ||
| markdown_content, | ||
| source_path=self.path, | ||
| start_line_offset=0, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I might be missing something here, but why is this a list? (seems like we are throwing away anything except the first element anyway)
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pytest returns a list because the hook can be defined multiple times. For example:
The default is to have a list that contains all the hooks and the nested
conftest.pygets called first so they are first in the hooks list.I simplified the code by using
@pytest.hookspec(firstresult=True), which returns the first one by default: 0be6a10Also, 5fe7f6f, which defines a default
MarkdownItparser using the hook.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I see, yeah this makes sense! Thanks for the explanation and I like the firstresult and default implementation