Bug 2353325

Summary: python-myst-parser fails to build with python-pygments 2.19 on Fedora 43
Product: [Fedora] Fedora Reporter: Karolina Surma <ksurma>
Component: python-myst-parserAssignee: Karolina Surma <ksurma>
Status: CLOSED RAWHIDE QA Contact:
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: rawhideCC: epel-packagers-sig, jonathan, ksurma, lbalhar, mhroncok, python-packagers-sig
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: ---
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2025-03-27 12:44:55 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 2322407, 2339432    

Description Karolina Surma 2025-03-19 09:16:00 UTC
python-myst-parser fails to build with python-sphinx 8.2.3 in Fedora 43.

The failure:

____________________________ test_extended_syntaxes ____________________________

app = <SphinxTestApp buildername='html'>
status = <_io.StringIO object at 0x7f71304b28c0>
warning = <_io.StringIO object at 0x7f71304b31c0>
get_sphinx_app_doctree = <function get_sphinx_app_doctree.<locals>.read at 0x7f71303f9620>
get_sphinx_app_output = <function get_sphinx_app_output.<locals>.read at 0x7f71303f9300>
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7f713056e190>

    @pytest.mark.sphinx(
        buildername="html",
        srcdir=os.path.join(SOURCE_DIR, "extended_syntaxes"),
        freshenv=True,
    )
    def test_extended_syntaxes(
        app,
        status,
        warning,
        get_sphinx_app_doctree,
        get_sphinx_app_output,
        monkeypatch,
    ):
        """test setting addition configuration values."""
        from myst_parser.mdit_to_docutils.sphinx_ import SphinxRenderer
    
        monkeypatch.setattr(SphinxRenderer, "_random_label", lambda self: "mock-uuid")
        app.build()
        assert "build succeeded" in status.getvalue()  # Build succeeded
        warnings = warning.getvalue().strip()
        assert warnings == ""
    
        try:
>           get_sphinx_app_doctree(
                app,
                docname="index",
                regress=True,
            )

tests/test_sphinx/test_sphinx_builds.py:241: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

app = <SphinxTestApp buildername='html'>, docname = 'index', resolve = False
regress = True, replace = None, rstrip_lines = False, regress_ext = '.xml'

    def read(
        app,
        docname="index",
        resolve=False,
        regress=False,
        replace=None,
        rstrip_lines=False,
        regress_ext=".xml",
    ):
        if resolve:
            doctree = app.env.get_and_resolve_doctree(docname, app.builder)
            extension = f".resolved{regress_ext}"
        else:
            doctree = app.env.get_doctree(docname)
            extension = regress_ext
    
        # convert absolute filenames
        for node in findall(doctree)(
            lambda n: "source" in n and not isinstance(n, str)
        ):
            node["source"] = pathlib.Path(node["source"]).name
    
        doctree = doctree.deepcopy()
    
        # remove attrs added in sphinx 7.1
        doctree.attributes.pop("translation_progress", None)
        for node in findall(doctree)(nodes.Element):
            node.attributes.pop("translated", None)
    
        if regress:
            text = doctree.pformat()  # type: str
            for find, rep in (replace or {}).items():
                text = text.replace(find, rep)
            if rstrip_lines:
                text = "\n".join([li.rstrip() for li in text.splitlines()])
>           file_regression.check(text, extension=extension)
E           AssertionError: FILES DIFFER:
E           /tmp/pytest-of-mockbuild/pytest-0/test_extended_syntaxes0/test_sphinx_builds/test_extended_syntaxes.xml
E           /tmp/pytest-of-mockbuild/pytest-0/test_extended_syntaxes0/test_sphinx_builds/test_extended_syntaxes.obtained.xml
E           HTML DIFF: /tmp/pytest-of-mockbuild/pytest-0/test_extended_syntaxes0/test_sphinx_builds/test_extended_syntaxes.obtained.diff.html
E           --- 
E           +++ 
E           @@ -26,7 +26,7 @@
E                        \begin{equation}
E                        b=2
E                        \end{equation}
E           -        <math_block docname="index" label="True" nowrap="False" number="True" xml:space="preserve">
E           +        <math_block docname="index" label="True" no-wrap="False" nowrap="False" number="True" xml:space="preserve">
E                        c=3
E                        
E                        d=4

tests/test_sphinx/conftest.py:135: AssertionError
--------------------------- Captured stdout teardown ---------------------------
# testroot: root
# builder: html
# srcdir: /builddir/build/BUILD/python-myst-parser-4.0.1-build/MyST-Parser-4.0.1/tests/test_sphinx/sourcedirs/extended_syntaxes
# outdir: /builddir/build/BUILD/python-myst-parser-4.0.1-build/MyST-Parser-4.0.1/tests/test_sphinx/sourcedirs/extended_syntaxes/_build/html
# status: 
Running Sphinx v8.2.3
loading translations [en]... done
myst v4.0.1: MdParserConfig(commonmark_only=False, gfm_only=False, enable_extensions={'tasklist', 'dollarmath', 'attrs_inline', 'amsmath', 'linkify', 'attrs_block', 'deflist', 'colon_fence'}, disable_syntax=['emphasis'], all_links_external=False, links_external_new_tab=False, url_schemes=('http', 'https', 'mailto', 'ftp'), ref_domains=None, fence_as_directive=set(), number_code_blocks=['typescript'], title_to_header=False, heading_anchors=0, heading_slug_func=None, html_meta={description lang=en: ..., property=og:locale: ...}, footnote_sort=True, footnote_transition=True, words_per_minute=200, substitutions={}, linkify_fuzzy_links=True, dmath_allow_labels=True, dmath_allow_space=False, dmath_allow_digits=True, dmath_double_inline=True, update_mathjax=True, mathjax_classes='tex2jax_process|mathjax_process|math|output_area', enable_checkboxes=False, suppress_warnings=[], highlight_code_blocks=True)
building [mo]: targets for 0 po files that are out of date
writing output... 
building [html]: targets for 1 source files that are out of date
updating environment: [new config] 1 added, 0 changed, 0 removed
reading sources... [100%] index

looking for now-outdated files... none found
pickling environment... done
checking consistency... done
preparing documents... done
copying assets... 
copying static files... 
Writing evaluated template result to /builddir/build/BUILD/python-myst-parser-4.0.1-build/MyST-Parser-4.0.1/tests/test_sphinx/sourcedirs/extended_syntaxes/_build/html/_static/basic.css
Writing evaluated template result to /builddir/build/BUILD/python-myst-parser-4.0.1-build/MyST-Parser-4.0.1/tests/test_sphinx/sourcedirs/extended_syntaxes/_build/html/_static/documentation_options.js
Writing evaluated template result to /builddir/build/BUILD/python-myst-parser-4.0.1-build/MyST-Parser-4.0.1/tests/test_sphinx/sourcedirs/extended_syntaxes/_build/html/_static/language_data.js
copying static files: done
copying extra files... 
copying extra files: done
copying assets: done
writing output... [100%] index

generating indices... genindex done
writing additional pages... search done
copying images... [100%] fun-fish.png

dumping search index in English (code: en)... done
dumping object inventory... done
build succeeded.

The HTML pages are in tests/test_sphinx/sourcedirs/extended_syntaxes/_build/html.

# warning: 

___________________________ test_fieldlist_extension ___________________________

app = <SphinxTestApp buildername='html'>
status = <_io.StringIO object at 0x7f712f9568c0>
warning = <_io.StringIO object at 0x7f712f799180>
get_sphinx_app_doctree = <function get_sphinx_app_doctree.<locals>.read at 0x7f712f6d47c0>
get_sphinx_app_output = <function get_sphinx_app_output.<locals>.read at 0x7f712f6d4900>

    @pytest.mark.sphinx(
        buildername="html",
        srcdir=os.path.join(SOURCE_DIR, "fieldlist"),
        freshenv=True,
    )
    def test_fieldlist_extension(
        app,
        status,
        warning,
        get_sphinx_app_doctree,
        get_sphinx_app_output,
    ):
        """test setting addition configuration values."""
        app.build()
        assert "build succeeded" in status.getvalue()  # Build succeeded
        warnings = warning.getvalue().strip()
        assert warnings == ""
    
        try:
>           get_sphinx_app_doctree(
                app,
                docname="index",
                regress=True,
                replace={
                    # changed in sphinx 7.2 for desc_sig_name node
                    'classes="n n"': 'classes="n"',
                    # changed in sphinx 7.2 for desc_parameterlist node
                    'multi_line_parameter_list="False" ': "",
                    # changed in sphinx 7.1 (but fixed in 7.2) for desc_signature/desc_name nodes
                    'classes="sig sig-object sig sig-object"': 'classes="sig sig-object"',
                    'classes="sig-name descname sig-name descname"': 'classes="sig-name descname"',
                    # changed in sphinx 7.2 (#11533)
                    (
                        'no-contents-entry="False" no-index="False" '
                        'no-index-entry="False" no-typesetting="False" '
                    ): "",
                },
            )

tests/test_sphinx/test_sphinx_builds.py:576: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

app = <SphinxTestApp buildername='html'>, docname = 'index', resolve = False
regress = True
replace = {'classes="n n"': 'classes="n"', 'classes="sig sig-object sig sig-object"': 'classes="sig sig-object"', 'classes="sig-name descname sig-name descname"': 'classes="sig-name descname"', 'multi_line_parameter_list="False" ': '', ...}
rstrip_lines = False, regress_ext = '.xml'

    def read(
        app,
        docname="index",
        resolve=False,
        regress=False,
        replace=None,
        rstrip_lines=False,
        regress_ext=".xml",
    ):
        if resolve:
            doctree = app.env.get_and_resolve_doctree(docname, app.builder)
            extension = f".resolved{regress_ext}"
        else:
            doctree = app.env.get_doctree(docname)
            extension = regress_ext
    
        # convert absolute filenames
        for node in findall(doctree)(
            lambda n: "source" in n and not isinstance(n, str)
        ):
            node["source"] = pathlib.Path(node["source"]).name
    
        doctree = doctree.deepcopy()
    
        # remove attrs added in sphinx 7.1
        doctree.attributes.pop("translation_progress", None)
        for node in findall(doctree)(nodes.Element):
            node.attributes.pop("translated", None)
    
        if regress:
            text = doctree.pformat()  # type: str
            for find, rep in (replace or {}).items():
                text = text.replace(find, rep)
            if rstrip_lines:
                text = "\n".join([li.rstrip() for li in text.splitlines()])
>           file_regression.check(text, extension=extension)
E           AssertionError: FILES DIFFER:
E           /tmp/pytest-of-mockbuild/pytest-0/test_fieldlist_extension0/test_sphinx_builds/test_fieldlist_extension.xml
E           /tmp/pytest-of-mockbuild/pytest-0/test_fieldlist_extension0/test_sphinx_builds/test_fieldlist_extension.obtained.xml
E           HTML DIFF: /tmp/pytest-of-mockbuild/pytest-0/test_fieldlist_extension0/test_sphinx_builds/test_fieldlist_extension.obtained.diff.html
E           --- 
E           +++ 
E           @@ -19,7 +19,7 @@
E                        <desc_signature _toc_name="send_message()" _toc_parts="('send_message',)" class="" classes="sig sig-object" fullname="send_message" ids="send_message" module="True">
E                            <desc_name classes="sig-name descname" xml:space="preserve">
E                                send_message
E           -                <desc_parameterlist xml:space="preserve">
E           +                <desc_parameterlist multi_line_trailing_comma="True" xml:space="preserve">
E                                <desc_parameter xml:space="preserve">
E                                    <desc_sig_name classes="n">
E                                        sender

The testing takes place in COPR:
https://copr.fedorainfracloud.org/coprs/ksurma/sphinx-8.2.3/package/python-myst-parser