Skip to content

[py3.12] Failing unit test: test_enum_class #10989

Closed

Description

@jayaddison

Describe the bug

This is a bug to track fixing a test failure in continuous integration. The test_enum_class unit test is currently failing when run on Python 3.12 (alpha), as seen in build logs here: https://github.com/sphinx-doc/sphinx/actions/runs/3487569464/jobs/5835351346#step:8:1868

E       AssertionError: assert ['', '.. py:class:: EnumCls(value, names=None, *values, module=None, qualname=None, type=None, start=1, boundary=None)', '   :module: target.enums', '', '   this is enum class', '', '', '   .. py:method:: EnumCls.say_goodbye()', '      :module: target.enums', '      :classmethod:', '', '      a classmethod says good-bye to you.', '', '', '   .. py:method:: EnumCls.say_hello()', '      :module: target.enums', '', '      a method says hello to you.', '', '', '   .. py:attribute:: EnumCls.val1', '      :module: target.enums', '      :value: 12', '', '      doc for val1', '', '', '   .. py:attribute:: EnumCls.val2', '      :module: target.enums', '      :value: 23', '', '      doc for val2', '', '', '   .. py:attribute:: EnumCls.val3', '      :module: target.enums', '      :value: 34', '', '      doc for val3', ''] == ['', '.. py:class:: EnumCls(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)', '   :module: target.enums', '', '   this is enum class', '', '', '   .. py:method:: EnumCls.say_goodbye()', '      :module: target.enums', '      :classmethod:', '', '      a classmethod says good-bye to you.', '', '', '   .. py:method:: EnumCls.say_hello()', '      :module: target.enums', '', '      a method says hello to you.', '', '', '   .. py:attribute:: EnumCls.val1', '      :module: target.enums', '      :value: 12', '', '      doc for val1', '', '', '   .. py:attribute:: EnumCls.val2', '      :module: target.enums', '      :value: 23', '', '      doc for val2', '', '', '   .. py:attribute:: EnumCls.val3', '      :module: target.enums', '      :value: 34', '', '      doc for val3', '']
E         At index 1 diff: '.. py:class:: EnumCls(value, names=None, *values, module=None, qualname=None, type=None, start=1, boundary=None)' != '.. py:class:: EnumCls(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)'
E         Full diff:
E           [
E            '',
E         -  '.. py:class:: EnumCls(value, names=None, *, module=None, qualname=None, '
E         ?                                                            ---------------
E         +  '.. py:class:: EnumCls(value, names=None, *values, module=None, '
E         ?                                             ++++++
E         -  'type=None, start=1, boundary=None)',
E         +  'qualname=None, type=None, start=1, boundary=None)',
E         ?   +++++++++++++++
E            '   :module: target.enums',
E            '',
E            '   this is enum class',
E            '',
E            '',
E            '   .. py:method:: EnumCls.say_goodbye()',
E            '      :module: target.enums',
E            '      :classmethod:',
E            '',
E            '      a classmethod says good-bye to you.',
E            '',
E            '',
E            '   .. py:method:: EnumCls.say_hello()',
E            '      :module: target.enums',
E            '',
E            '      a method says hello to you.',
E            '',
E            '',
E            '   .. py:attribute:: EnumCls.val1',
E            '      :module: target.enums',
E            '      :value: 12',
E            '',
E            '      doc for val1',
E            '',
E            '',
E            '   .. py:attribute:: EnumCls.val2',
E            '      :module: target.enums',
E            '      :value: 23',
E            '',
E            '      doc for val2',
E            '',
E            '',
E            '   .. py:attribute:: EnumCls.val3',
E            '      :module: target.enums',
E            '      :value: 34',
E            '',
E            '      doc for val3',
E            '',
E           ]

How to Reproduce

N/A - this is occurring when unit tests for the sphinx.git repository are run

See https://github.com/sphinx-doc/sphinx/actions/runs/3487569464/jobs/5835351346 for an example build log output.

Environment Information

N/A

Sphinx extensions

N/A

Additional context

Although test failures started occurring for Python 3.12 (alpha) onwards, the type signature emitted by Sphinx for EnumCls also changed for Python 3.11 (explaining this unit test condition).

The cause may be related to the fact that Python's Enum class has two signatures for the __call__ method, as described here: python/cpython#73549 (comment) -- one of them has signature (value), and the other has signature (value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None).

The latter method signature doesn't seem to have changed between Python 3.11.0 and Python 3.12.0a2:

https://github.com/python/cpython/blob/deaf509e8fc6e0363bd6f26d52ad42f976ec42f2/Lib/enum.py#L669
https://github.com/python/cpython/blob/3b9d793efcfd2c00c14ffbeab1a3389bf3b095ff/Lib/enum.py#L695

And the Sphinx code that emits the signatures seems to be calling the sphinx.util.stringify_signature method, so that could provide a starting point for debugging.

Activity

  1. jayaddison commented on Nov 23, 2022

    @jayaddison
    ContributorAuthor

    Note: similar to the autodoc handling of empty-class constructors, I think this may be a case where emitting the (value) signature for an Enum class makes for better readability overall.

    Certainly if the use case is documentation for a class derived from enum.Enum (as in the relevant test fixture data), then the appropriate signature to show is how to construct an element belonging to the enum (not the longer variation of the signature, which is used to define a new enumerable type).

  2. jayaddison commented on Nov 23, 2022

    @jayaddison
    ContributorAuthor

    Seems closely related / similar to #9442.

  3. jayaddison commented on Nov 23, 2022

    @jayaddison
    ContributorAuthor

    Although I think I've traced some of the relevant sections of code, I'm very confused about why a different type signature is being emitted on Python 3.12a2 and would appreciate any help.

  4. jayaddison commented on Dec 5, 2022

    @jayaddison
    ContributorAuthor

    cc @ethanfurman as a heads-up (this is probably an expected change in behaviour? I thought I'd check since it's appearing in sphinx-on-py3.12 unit test failures -- it seems to be related to method signatures for Enum types)

  5. ethanfurman commented on Dec 5, 2022

    @ethanfurman

    It is expected, and made in python/cpython#99500. The effective signature for looking up an enum member is:

    SomeEnum(*values)
    

    and for creating one:

    SomeBaseEnum(cls_name, members, *, module=None, qualname=None, type=None, start=1, boundary=None)
    

    Issue python/cpython#100039 will explore making that better.

  6. jayaddison commented on Dec 5, 2022

    @jayaddison
    ContributorAuthor

    Thanks @ethanfurman!

  7. changed the title [-]Failing unit test: test_enum_class[/-] [+][py3.12] Failing unit test: test_enum_class[/+] on Dec 29, 2022
  8. AA-Turner commented on Dec 30, 2022

    @AA-Turner
    Member

    Fixed in aeda313

    A

  9. jayaddison commented on Dec 30, 2022

    @jayaddison
    ContributorAuthor

    Thanks @AA-Turner!

  10. locked as resolved and limited conversation to collaborators on Jan 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions