77from collections .abc import Sequence
88from struct import Struct
99from types import TracebackType
10- from typing import Any , Callable , ForwardRef , TypeVar , Union
10+ from typing import TYPE_CHECKING , Any , Callable , ForwardRef , TypeVar , Union
1111
1212from docutils import nodes
1313from docutils .parsers .rst .states import Inliner
1414
15+ if TYPE_CHECKING :
16+ import enum
17+
1518try :
1619 from types import UnionType # type: ignore[attr-defined] # python 3.10 or above
1720except ImportError :
@@ -186,7 +189,14 @@ def restify(cls: type | None, mode: str = 'fully-qualified-except-typing') -> st
186189 args = ', ' .join (restify (a , mode ) for a in cls .__args__ [:- 1 ])
187190 text += fr"\ [[{ args } ], { restify (cls .__args__ [- 1 ], mode )} ]"
188191 elif cls .__module__ == 'typing' and getattr (origin , '_name' , None ) == 'Literal' :
189- text += r"\ [%s]" % ', ' .join (repr (a ) for a in cls .__args__ )
192+ literal_args = []
193+ for a in cls .__args__ :
194+ if inspect .isenumattribute (a ):
195+ literal_args .append (_format_literal_enum_arg (a , mode = mode ))
196+ else :
197+ literal_args .append (repr (a ))
198+ text += r"\ [%s]" % ', ' .join (literal_args )
199+ del literal_args
190200 elif cls .__args__ :
191201 text += r"\ [%s]" % ", " .join (restify (a , mode ) for a in cls .__args__ )
192202
@@ -338,7 +348,21 @@ def stringify_annotation(
338348 returns = stringify_annotation (annotation_args [- 1 ], mode )
339349 return f'{ module_prefix } Callable[[{ args } ], { returns } ]'
340350 elif qualname == 'Literal' :
341- args = ', ' .join (repr (a ) for a in annotation_args )
351+ from sphinx .util .inspect import isenumattribute # lazy loading
352+
353+ def format_literal_arg (arg ):
354+ if isenumattribute (arg ):
355+ enumcls = arg .__class__
356+
357+ if mode == 'smart' :
358+ # MyEnum.member
359+ return f'{ enumcls .__qualname__ } .{ arg .name } '
360+
361+ # module.MyEnum.member
362+ return f'{ enumcls .__module__ } .{ enumcls .__qualname__ } .{ arg .name } '
363+ return repr (arg )
364+
365+ args = ', ' .join (map (format_literal_arg , annotation_args ))
342366 return f'{ module_prefix } Literal[{ args } ]'
343367 elif str (annotation ).startswith ('typing.Annotated' ): # for py39+
344368 return stringify_annotation (annotation_args [0 ], mode )
@@ -352,6 +376,14 @@ def stringify_annotation(
352376 return module_prefix + qualname
353377
354378
379+ def _format_literal_enum_arg (arg : enum .Enum , / , * , mode : str ) -> str :
380+ enum_cls = arg .__class__
381+ if mode == 'smart' or enum_cls .__module__ == 'typing' :
382+ return f':py:attr:`~{ enum_cls .__module__ } .{ enum_cls .__qualname__ } .{ arg .name } `'
383+ else :
384+ return f':py:attr:`{ enum_cls .__module__ } .{ enum_cls .__qualname__ } .{ arg .name } `'
385+
386+
355387# deprecated name -> (object to return, canonical path or empty string)
356388_DEPRECATED_OBJECTS = {
357389 'stringify' : (stringify_annotation , 'sphinx.util.typing.stringify_annotation' ),
0 commit comments