Skip to content

🔧 Fix docutils deprecation in option parsing #842

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

Merged
merged 4 commits into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions myst_parser/_docs.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
"""Code to use internally, for documentation."""
from __future__ import annotations

import contextlib
import io
from typing import Sequence, Union, get_args, get_origin

from docutils import nodes
from docutils.frontend import OptionParser
from docutils.core import Publisher
from docutils.parsers.rst import directives
from sphinx.directives import other
from sphinx.transforms.post_transforms import SphinxPostTransform
Expand Down Expand Up @@ -175,11 +176,18 @@ class DocutilsCliHelpDirective(SphinxDirective):

def run(self):
"""Run the directive."""

stream = io.StringIO()
OptionParser(
components=(DocutilsParser,),
usage="myst-docutils-<writer> [options] [<source> [<destination>]]",
).print_help(stream)

pub = Publisher(parser=DocutilsParser())
with contextlib.redirect_stdout(stream):
try:
pub.process_command_line(
["--help"],
usage="myst-docutils-<writer> [options] [<source> [<destination>]]",
)
except SystemExit as exc:
assert not exc.code
return [nodes.literal_block("", stream.getvalue())]


Expand Down
11 changes: 9 additions & 2 deletions myst_parser/mdit_to_docutils/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@
)
from urllib.parse import urlparse

import docutils
import jinja2
import yaml
from docutils import nodes
from docutils.frontend import OptionParser
from docutils.languages import get_language
from docutils.parsers.rst import Directive, DirectiveError, directives, roles
from docutils.parsers.rst import Parser as RSTParser
Expand Down Expand Up @@ -63,7 +63,14 @@

def make_document(source_path="notset", parser_cls=RSTParser) -> nodes.document:
"""Create a new docutils document, with the parser classes' default settings."""
settings = OptionParser(components=(parser_cls,)).get_default_values()
if docutils.__version_info__[:2] >= (0, 19):
from docutils.frontend import get_default_settings

settings = get_default_settings(parser_cls)
else:
from docutils.frontend import OptionParser

settings = OptionParser(components=(parser_cls,)).get_default_values()
return new_document(source_path, settings=settings)


Expand Down
11 changes: 9 additions & 2 deletions tests/test_docutils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import contextlib
import io
from dataclasses import dataclass, field, fields
from textwrap import dedent
Expand Down Expand Up @@ -91,10 +92,16 @@ def test_cli_pseudoxml(monkeypatch, capsys):

def test_help_text():
"""Test retrieving settings help text."""
from docutils.frontend import OptionParser
from docutils.core import Publisher

stream = io.StringIO()
OptionParser(components=(Parser,)).print_help(stream)
pub = Publisher(parser=Parser())
with contextlib.redirect_stdout(stream):
try:
pub.process_command_line(["--help"])
except SystemExit as exc:
assert not exc.code

assert "MyST options" in stream.getvalue()


Expand Down
5 changes: 2 additions & 3 deletions tests/test_renderers/test_fixtures_docutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,8 @@ def settings_from_cmdline(cmdline: str | None) -> dict[str, Any]:
if cmdline is None or not cmdline.strip():
return {}
pub = Publisher(parser=Parser())
option_parser = pub.setup_option_parser()
try:
settings = option_parser.parse_args(shlex.split(cmdline)).__dict__
pub.process_command_line(shlex.split(cmdline))
except Exception as err:
raise AssertionError(f"Failed to parse commandline: {cmdline}\n{err}")
return settings
return vars(pub.settings)
6 changes: 2 additions & 4 deletions tests/test_renderers/test_myst_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,13 @@ def test_cmdline(file_params: ParamTestData):
if "heading_slug_func" in file_params.title and __version_info__ < (0, 18):
pytest.skip("dupnames ids changed in docutils 0.18")
pub = Publisher(parser=Parser())
option_parser = pub.setup_option_parser()
try:
settings = option_parser.parse_args(
shlex.split(file_params.description)
).__dict__
pub.process_command_line(shlex.split(file_params.description))
except Exception as err:
raise AssertionError(
f"Failed to parse commandline: {file_params.description}\n{err}"
)
settings = vars(pub.settings)
report_stream = StringIO()
settings["output_encoding"] = "unicode"
settings["warning_stream"] = report_stream
Expand Down