sphinx-doc / sphinx

The Sphinx documentation generator
https://www.sphinx-doc.org/
Other
6.46k stars 2.1k forks source link

test_autodoc_type_aliases failing on 3.12.4 #12430

Open mweinelt opened 3 months ago

mweinelt commented 3 months ago

Describe the bug

After upgrading to Python 3.12.4 the test_autodoc_type_aliases test fails on Sphinx 3.7.3.

sphinx> __________________________ test_autodoc_type_aliases ___________________________
sphinx> [gw26] linux -- Python 3.12.4 /nix/store/w23yb3ajva7rq12cwl2ax95fd6y530p9-python3-3.12.4/bin/python3.12
sphinx> 
sphinx> app = <SphinxTestApp buildername='text'>
sphinx> 
sphinx>     @pytest.mark.sphinx('text', testroot='ext-autodoc')
sphinx>     def test_autodoc_type_aliases(app):
sphinx>         # default
sphinx>         options = {"members": None}
sphinx>         actual = do_autodoc(app, 'module', 'target.autodoc_type_aliases', options)
sphinx> >       assert list(actual) == [
sphinx>             '',
sphinx>             '.. py:module:: target.autodoc_type_aliases',
sphinx>             '',
sphinx>             '',
sphinx>             '.. py:class:: Foo()',
sphinx>             '   :module: target.autodoc_type_aliases',
sphinx>             '',
sphinx>             '   docstring',
sphinx>             '',
sphinx>             '',
sphinx>             '   .. py:attribute:: Foo.attr1',
sphinx>             '      :module: target.autodoc_type_aliases',
sphinx>             '      :type: int',
sphinx>             '',
sphinx>             '      docstring',
sphinx>             '',
sphinx>             '',
sphinx>             '   .. py:attribute:: Foo.attr2',
sphinx>             '      :module: target.autodoc_type_aliases',
sphinx>             '      :type: int',
sphinx>             '',
sphinx>             '      docstring',
sphinx>             '',
sphinx>             '',
sphinx>             '.. py:function:: mult(x: int, y: int) -> int',
sphinx>             '                 mult(x: float, y: float) -> float',
sphinx>             '   :module: target.autodoc_type_aliases',
sphinx>             '',
sphinx>             '   docstring',
sphinx>             '',
sphinx>             '',
sphinx>             '.. py:function:: read(r: ~_io.BytesIO) -> ~_io.StringIO',
sphinx>             '   :module: target.autodoc_type_aliases',
sphinx>             '',
sphinx>             '   docstring',
sphinx>             '',
sphinx>             '',
sphinx>             '.. py:function:: sum(x: int, y: int) -> int',
sphinx>             '   :module: target.autodoc_type_aliases',
sphinx>             '',
sphinx>             '   docstring',
sphinx>             '',
sphinx>             '',
sphinx>             '.. py:data:: variable',
sphinx>             '   :module: target.autodoc_type_aliases',
sphinx>             '   :type: int',
sphinx>             '',
sphinx>             '   docstring',
sphinx>             '',
sphinx>             '',
sphinx>             '.. py:data:: variable2',
sphinx>             '   :module: target.autodoc_type_aliases',
sphinx>             '   :type: int',
sphinx>             '   :value: None',
sphinx>             '',
sphinx>             '   docstring',
sphinx>             '',
sphinx>             '',
sphinx>             '.. py:data:: variable3',
sphinx>             '   :module: target.autodoc_type_aliases',
sphinx>             '   :type: int | None',
sphinx>             '',
sphinx>             '   docstring',
sphinx>             '',
sphinx>         ]
sphinx> E       AssertionError: assert ['', '.. py:module:: target.autodoc_type_aliases', '', '', '.. py:class:: Foo()', '   :module: target.autodoc_type_aliases', '', '   docstring', '', '', '   .. py:attribute:: Foo.attr1', '      :module: target.autodoc_type_aliases', '      :type: int', '', '      docstring', '', '', '   .. py:attribute:: Foo.attr2', '      :module: target.autodoc_type_aliases', '      :type: int', '', '      docstring', '', '', '.. py:function:: mult(x: myint, y: myint) -> myint', '                 mult(x: float, y: float) -> float', '   :module: target.autodoc_type_aliases', '', '   docstring', '', '', '.. py:function:: read(r: ~_io.BytesIO) -> ~_io.StringIO', '   :module: target.autodoc_type_aliases', '', '   docstring', '', '', '.. py:function:: sum(x: int, y: int) -> int', '   :module: target.autodoc_type_aliases', '', '   docstring', '', '', '.. py:data:: variable', '   :module: target.autodoc_type_aliases', '   :type: int', '', '   docstring', '', '', '.. py:data:: variable2', '   :module: target.autodoc_type_aliases', '   :type: int', '   :value: None', '', '   docstring', '', '', '.. py:data:: variable3', '   :module: target.autodoc_type_aliases', '   :type: int | None', '', '   docstring', ''] == ['', '.. py:module:: target.autodoc_type_aliases', '', '', '.. py:class:: Foo()', '   :module: target.autodoc_type_aliases', '', '   docstring', '', '', '   .. py:attribute:: Foo.attr1', '      :module: target.autodoc_type_aliases', '      :type: int', '', '      docstring', '', '', '   .. py:attribute:: Foo.attr2', '      :module: target.autodoc_type_aliases', '      :type: int', '', '      docstring', '', '', '.. py:function:: mult(x: int, y: int) -> int', '                 mult(x: float, y: float) -> float', '   :module: target.autodoc_type_aliases', '', '   docstring', '', '', '.. py:function:: read(r: ~_io.BytesIO) -> ~_io.StringIO', '   :module: target.autodoc_type_aliases', '', '   docstring', '', '', '.. py:function:: sum(x: int, y: int) -> int', '   :module: target.autodoc_type_aliases', '', '   docstring', '', '', '.. py:data:: variable', '   :module: target.autodoc_type_aliases', '   :type: int', '', '   docstring', '', '', '.. py:data:: variable2', '   :module: target.autodoc_type_aliases', '   :type: int', '   :value: None', '', '   docstring', '', '', '.. py:data:: variable3', '   :module: target.autodoc_type_aliases', '   :type: int | None', '', '   docstring', '']
sphinx> E         
sphinx> E         At index 24 diff: '.. py:function:: mult(x: myint, y: myint) -> myint' != '.. py:function:: mult(x: int, y: int) -> int'
sphinx> E         
sphinx> E         Full diff:
sphinx> E           [
sphinx> E               '',
sphinx> E               '.. py:module:: target.autodoc_type_aliases',
sphinx> E               '',
sphinx> E               '',
sphinx> E               '.. py:class:: Foo()',
sphinx> E               '   :module: target.autodoc_type_aliases',
sphinx> E               '',
sphinx> E               '   docstring',
sphinx> E               '',
sphinx> E               '',
sphinx> E               '   .. py:attribute:: Foo.attr1',
sphinx> E               '      :module: target.autodoc_type_aliases',
sphinx> E               '      :type: int',
sphinx> E               '',
sphinx> E               '      docstring',
sphinx> E               '',
sphinx> E               '',
sphinx> E               '   .. py:attribute:: Foo.attr2',
sphinx> E               '      :module: target.autodoc_type_aliases',
sphinx> E               '      :type: int',
sphinx> E               '',
sphinx> E               '      docstring',
sphinx> E               '',
sphinx> E               '',
sphinx> E         -     '.. py:function:: mult(x: int, y: int) -> int',
sphinx> E         +     '.. py:function:: mult(x: myint, y: myint) -> myint',
sphinx> E         ?                               ++        ++        ++
sphinx> E               '                 mult(x: float, y: float) -> float',
sphinx> E               '   :module: target.autodoc_type_aliases',
sphinx> E               '',
sphinx> E               '   docstring',
sphinx> E               '',
sphinx> E               '',
sphinx> E               '.. py:function:: read(r: ~_io.BytesIO) -> ~_io.StringIO',
sphinx> E               '   :module: target.autodoc_type_aliases',
sphinx> E               '',
sphinx> E               '   docstring',
sphinx> E               '',
sphinx> E               '',
sphinx> E               '.. py:function:: sum(x: int, y: int) -> int',
sphinx> E               '   :module: target.autodoc_type_aliases',
sphinx> E               '',
sphinx> E               '   docstring',
sphinx> E               '',
sphinx> E               '',
sphinx> E               '.. py:data:: variable',
sphinx> E               '   :module: target.autodoc_type_aliases',
sphinx> E               '   :type: int',
sphinx> E               '',
sphinx> E               '   docstring',
sphinx> E               '',
sphinx> E               '',
sphinx> E               '.. py:data:: variable2',
sphinx> E               '   :module: target.autodoc_type_aliases',
sphinx> E               '   :type: int',
sphinx> E               '   :value: None',
sphinx> E               '',
sphinx> E               '   docstring',
sphinx> E               '',
sphinx> E               '',
sphinx> E               '.. py:data:: variable3',
sphinx> E               '   :module: target.autodoc_type_aliases',
sphinx> E               '   :type: int | None',
sphinx> E               '',
sphinx> E               '   docstring',
sphinx> E               '',
sphinx> E           ]
sphinx> 
sphinx> tests/test_extensions/test_ext_autodoc_configs.py:1258: AssertionError
sphinx> --------------------------- Captured stdout teardown ---------------------------
sphinx> # testroot: root
sphinx> # builder: text
sphinx> # srcdir: /build/pytest-of-nixbld/pytest-0/popen-gw26/ext-autodoc
sphinx> # outdir: /build/pytest-of-nixbld/pytest-0/popen-gw26/ext-autodoc/_build/text
sphinx> # status: 
sphinx> Running Sphinx v7.3.7
sphinx> 
sphinx> # warning: 
sphinx> 

How to Reproduce

Environment Information

Platform:              linux; (Linux-6.8.9-x86_64-with-glibc2.39)
Python version:        3.12.4 (main, Jun  6 2024, 18:26:44) [GCC 13.3.0])
Python implementation: CPython
Sphinx version:        7.3.7
Docutils version:      0.21.2
Jinja2 version:        3.1.4
Pygments version:      2.18.0

Sphinx extensions

Just the required ones:

sphinxcontrib-applehelp
sphinxcontrib-devhelp
sphinxcontrib-htmlhelp
sphinxcontrib-jsmath
sphinxcontrib-qthelp
sphinxcontrib-serializinghtml
sphinxcontrib-websupport

Additional context

No response

picnixz commented 3 months ago

Oh great, something changed again. I know I fixed this one at some point but I think it broke again. Let me check that.

Can you tell me whether it works or not on 3.13 and 3.14 or if it's 3.12 only? @mweinelt

mweinelt commented 3 months ago

Failing on 3.13.0b2 as well, even after picking 3496de62b743942115acb486cf35dfcc102586c3. We don't have 3.14 yet.

sphinx> __________________________ test_autodoc_type_aliases ___________________________
sphinx> [gw20] linux -- Python 3.13.0 /nix/store/f6wqbvfpzlcd5fc8rp6l4v8vkh3qg4y2-python3-3.13.0b2/bin/python3.13
sphinx> 
sphinx> app = <SphinxTestApp buildername='text'>
sphinx> 
sphinx>     @pytest.mark.sphinx('text', testroot='ext-autodoc')
sphinx>     def test_autodoc_type_aliases(app):
sphinx>         # default
sphinx>         options = {"members": None}
sphinx>         actual = do_autodoc(app, 'module', 'target.autodoc_type_aliases', options)
sphinx> >       assert list(actual) == [
sphinx>             '',
sphinx>             '.. py:module:: target.autodoc_type_aliases',
sphinx>             '',
sphinx>             '',
sphinx>             '.. py:class:: Foo()',
sphinx>             '   :module: target.autodoc_type_aliases',
sphinx>             '',
sphinx>             '   docstring',
sphinx>             '',
sphinx>             '',
sphinx>             '   .. py:attribute:: Foo.attr1',
sphinx>             '      :module: target.autodoc_type_aliases',
sphinx>             '      :type: int',
sphinx>             '',
sphinx>             '      docstring',
sphinx>             '',
sphinx>             '',
sphinx>             '   .. py:attribute:: Foo.attr2',
sphinx>             '      :module: target.autodoc_type_aliases',
sphinx>             '      :type: int',
sphinx>             '',
sphinx>             '      docstring',
sphinx>             '',
sphinx>             '',
sphinx>             '.. py:function:: mult(x: int, y: int) -> int',
sphinx>             '                 mult(x: float, y: float) -> float',
sphinx>             '   :module: target.autodoc_type_aliases',
sphinx>             '',
sphinx>             '   docstring',
sphinx>             '',
sphinx>             '',
sphinx>             '.. py:function:: read(r: ~_io.BytesIO) -> ~_io.StringIO',
sphinx>             '   :module: target.autodoc_type_aliases',
sphinx>             '',
sphinx>             '   docstring',
sphinx>             '',
sphinx>             '',
sphinx>             '.. py:function:: sum(x: int, y: int) -> int',
sphinx>             '   :module: target.autodoc_type_aliases',
sphinx>             '',
sphinx>             '   docstring',
sphinx>             '',
sphinx>             '',
sphinx>             '.. py:data:: variable',
sphinx>             '   :module: target.autodoc_type_aliases',
sphinx>             '   :type: int',
sphinx>             '',
sphinx>             '   docstring',
sphinx>             '',
sphinx>             '',
sphinx>             '.. py:data:: variable2',
sphinx>             '   :module: target.autodoc_type_aliases',
sphinx>             '   :type: int',
sphinx>             '   :value: None',
sphinx>             '',
sphinx>             '   docstring',
sphinx>             '',
sphinx>             '',
sphinx>             '.. py:data:: variable3',
sphinx>             '   :module: target.autodoc_type_aliases',
sphinx>             '   :type: int | None',
sphinx>             '',
sphinx>             '   docstring',
sphinx>             '',
sphinx>         ]
sphinx> E       AssertionError: assert ['', '.. py:module:: target.autodoc_type_aliases', '', '', '.. py:class:: Foo()', '   :module: target.autodoc_type_aliases', '', '   docstring', '', '', '   .. py:attribute:: Foo.attr1', '      :module: target.autodoc_type_aliases', '      :type: int', '', '      docstring', '', '', '   .. py:attribute:: Foo.attr2', '      :module: target.autodoc_type_aliases', '      :type: int', '', '      docstring', '', '', '.. py:function:: mult(x: myint, y: myint) -> myint', '                 mult(x: float, y: float) -> float', '   :module: target.autodoc_type_aliases', '', '   docstring', '', '', '.. py:function:: read(r: ~_io.BytesIO) -> ~_io.StringIO', '   :module: target.autodoc_type_aliases', '', '   docstring', '', '', '.. py:function:: sum(x: int, y: int) -> int', '   :module: target.autodoc_type_aliases', '', '   docstring', '', '', '.. py:data:: variable', '   :module: target.autodoc_type_aliases', '   :type: int', '', '   docstring', '', '', '.. py:data:: variable2', '   :module: target.autodoc_type_aliases', '   :type: int', '   :value: None', '', '   docstring', '', '', '.. py:data:: variable3', '   :module: target.autodoc_type_aliases', '   :type: int | None', '', '   docstring', ''] == ['', '.. py:module:: target.autodoc_type_aliases', '', '', '.. py:class:: Foo()', '   :module: target.autodoc_type_aliases', '', '   docstring', '', '', '   .. py:attribute:: Foo.attr1', '      :module: target.autodoc_type_aliases', '      :type: int', '', '      docstring', '', '', '   .. py:attribute:: Foo.attr2', '      :module: target.autodoc_type_aliases', '      :type: int', '', '      docstring', '', '', '.. py:function:: mult(x: int, y: int) -> int', '                 mult(x: float, y: float) -> float', '   :module: target.autodoc_type_aliases', '', '   docstring', '', '', '.. py:function:: read(r: ~_io.BytesIO) -> ~_io.StringIO', '   :module: target.autodoc_type_aliases', '', '   docstring', '', '', '.. py:function:: sum(x: int, y: int) -> int', '   :module: target.autodoc_type_aliases', '', '   docstring', '', '', '.. py:data:: variable', '   :module: target.autodoc_type_aliases', '   :type: int', '', '   docstring', '', '', '.. py:data:: variable2', '   :module: target.autodoc_type_aliases', '   :type: int', '   :value: None', '', '   docstring', '', '', '.. py:data:: variable3', '   :module: target.autodoc_type_aliases', '   :type: int | None', '', '   docstring', '']
sphinx> E         
sphinx> E         At index 24 diff: '.. py:function:: mult(x: myint, y: myint) -> myint' != '.. py:function:: mult(x: int, y: int) -> int'
sphinx> E         
sphinx> E         Full diff:
sphinx> E           [
sphinx> E               '',
sphinx> E               '.. py:module:: target.autodoc_type_aliases',
sphinx> E               '',
sphinx> E               '',
sphinx> E               '.. py:class:: Foo()',
sphinx> E               '   :module: target.autodoc_type_aliases',
sphinx> E               '',
sphinx> E               '   docstring',
sphinx> E               '',
sphinx> E               '',
sphinx> E               '   .. py:attribute:: Foo.attr1',
sphinx> E               '      :module: target.autodoc_type_aliases',
sphinx> E               '      :type: int',
sphinx> E               '',
sphinx> E               '      docstring',
sphinx> E               '',
sphinx> E               '',
sphinx> E               '   .. py:attribute:: Foo.attr2',
sphinx> E               '      :module: target.autodoc_type_aliases',
sphinx> E               '      :type: int',
sphinx> E               '',
sphinx> E               '      docstring',
sphinx> E               '',
sphinx> E               '',
sphinx> E         -     '.. py:function:: mult(x: int, y: int) -> int',
sphinx> E         +     '.. py:function:: mult(x: myint, y: myint) -> myint',
sphinx> E         ?                               ++        ++        ++
sphinx> E               '                 mult(x: float, y: float) -> float',
sphinx> E               '   :module: target.autodoc_type_aliases',
sphinx> E               '',
sphinx> E               '   docstring',
sphinx> E               '',
sphinx> E               '',
sphinx> E               '.. py:function:: read(r: ~_io.BytesIO) -> ~_io.StringIO',
sphinx> E               '   :module: target.autodoc_type_aliases',
sphinx> E               '',
sphinx> E               '   docstring',
sphinx> E               '',
sphinx> E               '',
sphinx> E               '.. py:function:: sum(x: int, y: int) -> int',
sphinx> E               '   :module: target.autodoc_type_aliases',
sphinx> E               '',
sphinx> E               '   docstring',
sphinx> E               '',
sphinx> E               '',
sphinx> E               '.. py:data:: variable',
sphinx> E               '   :module: target.autodoc_type_aliases',
sphinx> E               '   :type: int',
sphinx> E               '',
sphinx> E               '   docstring',
sphinx> E               '',
sphinx> E               '',
sphinx> E               '.. py:data:: variable2',
sphinx> E               '   :module: target.autodoc_type_aliases',
sphinx> E               '   :type: int',
sphinx> E               '   :value: None',
sphinx> E               '',
sphinx> E               '   docstring',
sphinx> E               '',
sphinx> E               '',
sphinx> E               '.. py:data:: variable3',
sphinx> E               '   :module: target.autodoc_type_aliases',
sphinx> E               '   :type: int | None',
sphinx> E               '',
sphinx> E               '   docstring',
sphinx> E               '',
sphinx> E           ]
sphinx> 
sphinx> tests/test_extensions/test_ext_autodoc_configs.py:1258: AssertionError
picnixz commented 3 months ago

I suspect that 3.14 will also be affected. I do not have a build of 3.12 currently and I was going offline in a few minutes (and not here tomorrow).

I'm surprised that the failure has not been caught yet because your build is a fairly recent one (and the nightly 3.12 should technically be tested AFAIK).

Now, what could have happened is that the parser is now able to recognize aliases correctly, namely myint = int and def foo(x: myint, y: myint) -> myint now gives you myint. Before, we needed this additional configuration because 'myint' was replaced by 'int' but it appears it's not the case anymore (as you can see, the test failing is the first one, where no alias is defined, and before the alias myint had the name 'int' and not 'myint' but it appears it's no more the case, or something like that).

So, it might be because of the recent changes on get_type_hints but I'm not sure whether those were actually backported to Python 3.12.4 for your build (June 6th).

@chrisjsewell can you check when you have some time?