Skip to content

Commit eb6e137

Browse files
committed
Merge _py37 functions in util.typing
- restify and _restify_py37 - stringify and _stringify_py37
1 parent dd7f65c commit eb6e137

File tree

1 file changed

+54
-245
lines changed

1 file changed

+54
-245
lines changed

sphinx/util/typing.py

Lines changed: 54 additions & 245 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,13 @@
22

33
import sys
44
import typing
5-
import warnings
65
from struct import Struct
76
from types import TracebackType
8-
from typing import (Any, Callable, Dict, ForwardRef, Generator, List, Optional, Tuple, Type,
9-
TypeVar, Union)
7+
from typing import Any, Callable, Dict, ForwardRef, List, Optional, Tuple, Type, TypeVar, Union
108

119
from docutils import nodes
1210
from docutils.parsers.rst.states import Inliner
1311

14-
from sphinx.deprecation import RemovedInSphinx70Warning
15-
1612
try:
1713
from types import UnionType # type: ignore # python 3.10 or above
1814
except ImportError:
@@ -143,176 +139,64 @@ def restify(cls: Optional[Type], mode: str = 'fully-qualified-except-typing') ->
143139
)
144140
else:
145141
return ':py:class:`%s`' % cls.__name__
146-
else:
147-
return _restify_py37(cls, mode)
148-
except (AttributeError, TypeError):
149-
return inspect.object_description(cls)
150-
151-
152-
def _restify_py37(cls: Optional[Type], mode: str = 'fully-qualified-except-typing') -> str:
153-
"""Convert python class to a reST reference."""
154-
from sphinx.util import inspect # lazy loading
155-
156-
if mode == 'smart':
157-
modprefix = '~'
158-
else:
159-
modprefix = ''
160-
161-
if (inspect.isgenericalias(cls) and
162-
cls.__module__ == 'typing' and cls.__origin__ is Union):
163-
# Union
164-
if len(cls.__args__) > 1 and cls.__args__[-1] is NoneType:
165-
if len(cls.__args__) > 2:
166-
args = ', '.join(restify(a, mode) for a in cls.__args__[:-1])
167-
return ':py:obj:`~typing.Optional`\\ [:obj:`~typing.Union`\\ [%s]]' % args
168-
else:
169-
return ':py:obj:`~typing.Optional`\\ [%s]' % restify(cls.__args__[0], mode)
170-
else:
171-
args = ', '.join(restify(a, mode) for a in cls.__args__)
172-
return ':py:obj:`~typing.Union`\\ [%s]' % args
173-
elif inspect.isgenericalias(cls):
174-
if isinstance(cls.__origin__, typing._SpecialForm):
175-
text = restify(cls.__origin__, mode) # type: ignore
176-
elif getattr(cls, '_name', None):
177-
if cls.__module__ == 'typing':
178-
text = ':py:class:`~%s.%s`' % (cls.__module__, cls._name)
142+
elif (inspect.isgenericalias(cls) and
143+
cls.__module__ == 'typing' and cls.__origin__ is Union):
144+
# Union
145+
if len(cls.__args__) > 1 and cls.__args__[-1] is NoneType:
146+
if len(cls.__args__) > 2:
147+
args = ', '.join(restify(a, mode) for a in cls.__args__[:-1])
148+
return ':py:obj:`~typing.Optional`\\ [:obj:`~typing.Union`\\ [%s]]' % args
149+
else:
150+
return ':py:obj:`~typing.Optional`\\ [%s]' % restify(cls.__args__[0], mode)
179151
else:
180-
text = ':py:class:`%s%s.%s`' % (modprefix, cls.__module__, cls._name)
181-
else:
182-
text = restify(cls.__origin__, mode)
183-
184-
origin = getattr(cls, '__origin__', None)
185-
if not hasattr(cls, '__args__'):
186-
pass
187-
elif all(is_system_TypeVar(a) for a in cls.__args__):
188-
# Suppress arguments if all system defined TypeVars (ex. Dict[KT, VT])
189-
pass
190-
elif cls.__module__ == 'typing' and cls._name == 'Callable':
191-
args = ', '.join(restify(a, mode) for a in cls.__args__[:-1])
192-
text += r"\ [[%s], %s]" % (args, restify(cls.__args__[-1], mode))
193-
elif cls.__module__ == 'typing' and getattr(origin, '_name', None) == 'Literal':
194-
text += r"\ [%s]" % ', '.join(repr(a) for a in cls.__args__)
195-
elif cls.__args__:
196-
text += r"\ [%s]" % ", ".join(restify(a, mode) for a in cls.__args__)
197-
198-
return text
199-
elif isinstance(cls, typing._SpecialForm):
200-
return ':py:obj:`~%s.%s`' % (cls.__module__, cls._name)
201-
elif sys.version_info[:2] >= (3, 11) and cls is typing.Any:
202-
# handle bpo-46998
203-
return f':py:obj:`~{cls.__module__}.{cls.__name__}`'
204-
elif hasattr(cls, '__qualname__'):
205-
if cls.__module__ == 'typing':
206-
return ':py:class:`~%s.%s`' % (cls.__module__, cls.__qualname__)
207-
else:
208-
return ':py:class:`%s%s.%s`' % (modprefix, cls.__module__, cls.__qualname__)
209-
elif isinstance(cls, ForwardRef):
210-
return ':py:class:`%s`' % cls.__forward_arg__
211-
else:
212-
# not a class (ex. TypeVar)
213-
if cls.__module__ == 'typing':
214-
return ':py:obj:`~%s.%s`' % (cls.__module__, cls.__name__)
215-
else:
216-
return ':py:obj:`%s%s.%s`' % (modprefix, cls.__module__, cls.__name__)
217-
218-
219-
def _restify_py36(cls: Optional[Type], mode: str = 'fully-qualified-except-typing') -> str:
220-
warnings.warn('_restify_py36() is deprecated', RemovedInSphinx70Warning)
221-
222-
if mode == 'smart':
223-
modprefix = '~'
224-
else:
225-
modprefix = ''
226-
227-
module = getattr(cls, '__module__', None)
228-
if module == 'typing':
229-
if getattr(cls, '_name', None):
230-
qualname = cls._name
231-
elif getattr(cls, '__qualname__', None):
232-
qualname = cls.__qualname__
233-
elif getattr(cls, '__forward_arg__', None):
234-
qualname = cls.__forward_arg__
235-
elif getattr(cls, '__origin__', None):
236-
qualname = stringify(cls.__origin__) # ex. Union
237-
else:
238-
qualname = repr(cls).replace('typing.', '')
239-
elif hasattr(cls, '__qualname__'):
240-
qualname = '%s%s.%s' % (modprefix, module, cls.__qualname__)
241-
else:
242-
qualname = repr(cls)
243-
244-
if (isinstance(cls, typing.TupleMeta) and # type: ignore
245-
not hasattr(cls, '__tuple_params__')):
246-
if module == 'typing':
247-
reftext = ':py:class:`~typing.%s`' % qualname
248-
else:
249-
reftext = ':py:class:`%s%s`' % (modprefix, qualname)
250-
251-
params = cls.__args__
252-
if params:
253-
param_str = ', '.join(restify(p, mode) for p in params)
254-
return reftext + '\\ [%s]' % param_str
255-
else:
256-
return reftext
257-
elif isinstance(cls, typing.GenericMeta): # type: ignore[attr-defined]
258-
if module == 'typing':
259-
reftext = ':py:class:`~typing.%s`' % qualname
260-
else:
261-
reftext = ':py:class:`%s%s`' % (modprefix, qualname)
262-
263-
if cls.__args__ is None or len(cls.__args__) <= 2:
264-
params = cls.__args__
265-
elif cls.__origin__ == Generator:
266-
params = cls.__args__
267-
else: # typing.Callable
268-
args = ', '.join(restify(arg, mode) for arg in cls.__args__[:-1])
269-
result = restify(cls.__args__[-1], mode)
270-
return reftext + '\\ [[%s], %s]' % (args, result)
271-
272-
if params:
273-
param_str = ', '.join(restify(p, mode) for p in params)
274-
return reftext + '\\ [%s]' % (param_str)
275-
else:
276-
return reftext
277-
elif (hasattr(cls, '__origin__') and
278-
cls.__origin__ is typing.Union):
279-
params = cls.__args__
280-
if params is not None:
281-
if len(params) > 1 and params[-1] is NoneType:
282-
if len(params) > 2:
283-
param_str = ", ".join(restify(p, mode) for p in params[:-1])
284-
return (':py:obj:`~typing.Optional`\\ '
285-
'[:py:obj:`~typing.Union`\\ [%s]]' % param_str)
152+
args = ', '.join(restify(a, mode) for a in cls.__args__)
153+
return ':py:obj:`~typing.Union`\\ [%s]' % args
154+
elif inspect.isgenericalias(cls):
155+
if isinstance(cls.__origin__, typing._SpecialForm):
156+
text = restify(cls.__origin__, mode) # type: ignore
157+
elif getattr(cls, '_name', None):
158+
if cls.__module__ == 'typing':
159+
text = ':py:class:`~%s.%s`' % (cls.__module__, cls._name)
286160
else:
287-
return ':py:obj:`~typing.Optional`\\ [%s]' % restify(params[0], mode)
161+
text = ':py:class:`%s%s.%s`' % (modprefix, cls.__module__, cls._name)
288162
else:
289-
param_str = ', '.join(restify(p, mode) for p in params)
290-
return ':py:obj:`~typing.Union`\\ [%s]' % param_str
291-
else:
292-
return ':py:obj:`Union`'
293-
elif hasattr(cls, '__qualname__'):
294-
if cls.__module__ == 'typing':
295-
return ':py:class:`~%s.%s`' % (cls.__module__, cls.__qualname__)
296-
else:
297-
return ':py:class:`%s%s.%s`' % (modprefix, cls.__module__, cls.__qualname__)
298-
elif hasattr(cls, '_name'):
299-
# SpecialForm
300-
if cls.__module__ == 'typing':
163+
text = restify(cls.__origin__, mode)
164+
165+
origin = getattr(cls, '__origin__', None)
166+
if not hasattr(cls, '__args__'):
167+
pass
168+
elif all(is_system_TypeVar(a) for a in cls.__args__):
169+
# Suppress arguments if all system defined TypeVars (ex. Dict[KT, VT])
170+
pass
171+
elif cls.__module__ == 'typing' and cls._name == 'Callable':
172+
args = ', '.join(restify(a, mode) for a in cls.__args__[:-1])
173+
text += r"\ [[%s], %s]" % (args, restify(cls.__args__[-1], mode))
174+
elif cls.__module__ == 'typing' and getattr(origin, '_name', None) == 'Literal':
175+
text += r"\ [%s]" % ', '.join(repr(a) for a in cls.__args__)
176+
elif cls.__args__:
177+
text += r"\ [%s]" % ", ".join(restify(a, mode) for a in cls.__args__)
178+
179+
return text
180+
elif isinstance(cls, typing._SpecialForm):
301181
return ':py:obj:`~%s.%s`' % (cls.__module__, cls._name)
182+
elif sys.version_info[:2] >= (3, 11) and cls is typing.Any:
183+
# handle bpo-46998
184+
return f':py:obj:`~{cls.__module__}.{cls.__name__}`'
185+
elif hasattr(cls, '__qualname__'):
186+
if cls.__module__ == 'typing':
187+
return ':py:class:`~%s.%s`' % (cls.__module__, cls.__qualname__)
188+
else:
189+
return ':py:class:`%s%s.%s`' % (modprefix, cls.__module__, cls.__qualname__)
190+
elif isinstance(cls, ForwardRef):
191+
return ':py:class:`%s`' % cls.__forward_arg__
302192
else:
303-
return ':py:obj:`%s%s.%s`' % (modprefix, cls.__module__, cls._name)
304-
elif hasattr(cls, '__name__'):
305-
# not a class (ex. TypeVar)
306-
if cls.__module__ == 'typing':
307-
return ':py:obj:`~%s.%s`' % (cls.__module__, cls.__name__)
308-
else:
309-
return ':py:obj:`%s%s.%s`' % (modprefix, cls.__module__, cls.__name__)
310-
else:
311-
# others (ex. Any)
312-
if cls.__module__ == 'typing':
313-
return ':py:obj:`~%s.%s`' % (cls.__module__, qualname)
314-
else:
315-
return ':py:obj:`%s%s.%s`' % (modprefix, cls.__module__, qualname)
193+
# not a class (ex. TypeVar)
194+
if cls.__module__ == 'typing':
195+
return ':py:obj:`~%s.%s`' % (cls.__module__, cls.__name__)
196+
else:
197+
return ':py:obj:`%s%s.%s`' % (modprefix, cls.__module__, cls.__name__)
198+
except (AttributeError, TypeError):
199+
return inspect.object_description(cls)
316200

317201

318202
def stringify(annotation: Any, mode: str = 'fully-qualified-except-typing') -> str:
@@ -375,11 +259,6 @@ def stringify(annotation: Any, mode: str = 'fully-qualified-except-typing') -> s
375259
elif annotation is Ellipsis:
376260
return '...'
377261

378-
return _stringify_py37(annotation, mode)
379-
380-
381-
def _stringify_py37(annotation: Any, mode: str = 'fully-qualified-except-typing') -> str:
382-
"""stringify() for py37+."""
383262
module = getattr(annotation, '__module__', None)
384263
modprefix = ''
385264
if module == 'typing' and getattr(annotation, '__forward_arg__', None):
@@ -450,73 +329,3 @@ def _stringify_py37(annotation: Any, mode: str = 'fully-qualified-except-typing'
450329
return '%s%s[%s]' % (modprefix, qualname, args)
451330

452331
return modprefix + qualname
453-
454-
455-
def _stringify_py36(annotation: Any, mode: str = 'fully-qualified-except-typing') -> str:
456-
"""stringify() for py36."""
457-
warnings.warn('_stringify_py36() is deprecated', RemovedInSphinx70Warning)
458-
459-
module = getattr(annotation, '__module__', None)
460-
modprefix = ''
461-
if module == 'typing' and getattr(annotation, '__forward_arg__', None):
462-
qualname = annotation.__forward_arg__
463-
elif module == 'typing':
464-
if getattr(annotation, '_name', None):
465-
qualname = annotation._name
466-
elif getattr(annotation, '__qualname__', None):
467-
qualname = annotation.__qualname__
468-
elif getattr(annotation, '__origin__', None):
469-
qualname = stringify(annotation.__origin__) # ex. Union
470-
else:
471-
qualname = repr(annotation).replace('typing.', '')
472-
473-
if mode == 'smart':
474-
modprefix = '~%s.' % module
475-
elif mode == 'fully-qualified':
476-
modprefix = '%s.' % module
477-
elif hasattr(annotation, '__qualname__'):
478-
if mode == 'smart':
479-
modprefix = '~%s.' % module
480-
else:
481-
modprefix = '%s.' % module
482-
qualname = annotation.__qualname__
483-
else:
484-
qualname = repr(annotation)
485-
486-
if (isinstance(annotation, typing.TupleMeta) and # type: ignore
487-
not hasattr(annotation, '__tuple_params__')): # for Python 3.6
488-
params = annotation.__args__
489-
if params:
490-
param_str = ', '.join(stringify(p, mode) for p in params)
491-
return '%s%s[%s]' % (modprefix, qualname, param_str)
492-
else:
493-
return modprefix + qualname
494-
elif isinstance(annotation, typing.GenericMeta): # type: ignore[attr-defined]
495-
params = None
496-
if annotation.__args__ is None or len(annotation.__args__) <= 2: # NOQA
497-
params = annotation.__args__
498-
elif annotation.__origin__ == Generator:
499-
params = annotation.__args__
500-
else: # typing.Callable
501-
args = ', '.join(stringify(arg, mode) for arg
502-
in annotation.__args__[:-1])
503-
result = stringify(annotation.__args__[-1])
504-
return '%s%s[[%s], %s]' % (modprefix, qualname, args, result)
505-
if params is not None:
506-
param_str = ', '.join(stringify(p, mode) for p in params)
507-
return '%s%s[%s]' % (modprefix, qualname, param_str)
508-
elif (hasattr(annotation, '__origin__') and
509-
annotation.__origin__ is typing.Union):
510-
params = annotation.__args__
511-
if params is not None:
512-
if len(params) > 1 and params[-1] is NoneType:
513-
if len(params) > 2:
514-
param_str = ", ".join(stringify(p, mode) for p in params[:-1])
515-
return '%sOptional[%sUnion[%s]]' % (modprefix, modprefix, param_str)
516-
else:
517-
return '%sOptional[%s]' % (modprefix, stringify(params[0], mode))
518-
else:
519-
param_str = ', '.join(stringify(p, mode) for p in params)
520-
return '%sUnion[%s]' % (modprefix, param_str)
521-
522-
return modprefix + qualname

0 commit comments

Comments
 (0)