22
33from __future__ import annotations
44
5+ import dataclasses
56import sys
67import types
78import typing
@@ -157,6 +158,7 @@ def get_type_hints(
157158 obj : Any ,
158159 globalns : dict [str , Any ] | None = None ,
159160 localns : dict [str , Any ] | None = None ,
161+ include_extras : bool = False ,
160162) -> dict [str , Any ]:
161163 """Return a dictionary containing type hints for a function, method, module or class
162164 object.
@@ -167,7 +169,7 @@ def get_type_hints(
167169 from sphinx .util .inspect import safe_getattr # lazy loading
168170
169171 try :
170- return typing .get_type_hints (obj , globalns , localns )
172+ return typing .get_type_hints (obj , globalns , localns , include_extras = include_extras )
171173 except NameError :
172174 # Failed to evaluate ForwardRef (maybe TYPE_CHECKING)
173175 return safe_getattr (obj , '__annotations__' , {})
@@ -267,7 +269,20 @@ def restify(cls: Any, mode: _RestifyMode = 'fully-qualified-except-typing') -> s
267269 return f':py:class:`{ module_prefix } { _INVALID_BUILTIN_CLASSES [cls ]} `'
268270 elif _is_annotated_form (cls ):
269271 args = restify (cls .__args__ [0 ], mode )
270- meta = ', ' .join (map (repr , cls .__metadata__ ))
272+ meta_args = []
273+ for m in cls .__metadata__ :
274+ if isinstance (m , type ):
275+ meta_args .append (stringify_annotation (m , mode ))
276+ elif dataclasses .is_dataclass (m ):
277+ # use stringify_annotation for the repr of field values rather than repr
278+ d_fields = ', ' .join ([
279+ f"{ f .name } ={ restify (getattr (m , f .name ), mode )} "
280+ for f in dataclasses .fields (m ) if f .repr
281+ ])
282+ meta_args .append (f'{ stringify_annotation (type (m ), mode )} ({ d_fields } )' )
283+ else :
284+ meta_args .append (repr (m ))
285+ meta = ', ' .join (meta_args )
271286 if sys .version_info [:2 ] <= (3 , 11 ):
272287 # Hardcoded to fix errors on Python 3.11 and earlier.
273288 return fr':py:class:`~typing.Annotated`\ [{ args } , { meta } ]'
@@ -510,7 +525,20 @@ def stringify_annotation(
510525 return f'{ module_prefix } Literal[{ args } ]'
511526 elif _is_annotated_form (annotation ): # for py39+
512527 args = stringify_annotation (annotation_args [0 ], mode )
513- meta = ', ' .join (map (repr , annotation .__metadata__ ))
528+ meta_args = []
529+ for m in annotation .__metadata__ :
530+ if isinstance (m , type ):
531+ meta_args .append (stringify_annotation (m , mode ))
532+ elif dataclasses .is_dataclass (m ):
533+ # use stringify_annotation for the repr of field values rather than repr
534+ d_fields = ', ' .join ([
535+ f"{ f .name } ={ stringify_annotation (getattr (m , f .name ), mode )} "
536+ for f in dataclasses .fields (m ) if f .repr
537+ ])
538+ meta_args .append (f'{ stringify_annotation (type (m ), mode )} ({ d_fields } )' )
539+ else :
540+ meta_args .append (repr (m ))
541+ meta = ', ' .join (meta_args )
514542 if sys .version_info [:2 ] <= (3 , 11 ):
515543 if mode == 'fully-qualified-except-typing' :
516544 return f'Annotated[{ args } , { meta } ]'
0 commit comments