|
2 | 2 |
|
3 | 3 | import sys |
4 | 4 | import typing |
5 | | -import warnings |
6 | 5 | from struct import Struct |
7 | 6 | 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 |
10 | 8 |
|
11 | 9 | from docutils import nodes |
12 | 10 | from docutils.parsers.rst.states import Inliner |
13 | 11 |
|
14 | | -from sphinx.deprecation import RemovedInSphinx70Warning |
15 | | - |
16 | 12 | try: |
17 | 13 | from types import UnionType # type: ignore # python 3.10 or above |
18 | 14 | except ImportError: |
@@ -143,176 +139,64 @@ def restify(cls: Optional[Type], mode: str = 'fully-qualified-except-typing') -> |
143 | 139 | ) |
144 | 140 | else: |
145 | 141 | 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) |
179 | 151 | 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) |
286 | 160 | else: |
287 | | - return ':py:obj:`~typing.Optional`\\ [%s]' % restify(params[0], mode) |
| 161 | + text = ':py:class:`%s%s.%s`' % (modprefix, cls.__module__, cls._name) |
288 | 162 | 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): |
301 | 181 | 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__ |
302 | 192 | 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) |
316 | 200 |
|
317 | 201 |
|
318 | 202 | 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 |
375 | 259 | elif annotation is Ellipsis: |
376 | 260 | return '...' |
377 | 261 |
|
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+.""" |
383 | 262 | module = getattr(annotation, '__module__', None) |
384 | 263 | modprefix = '' |
385 | 264 | if module == 'typing' and getattr(annotation, '__forward_arg__', None): |
@@ -450,73 +329,3 @@ def _stringify_py37(annotation: Any, mode: str = 'fully-qualified-except-typing' |
450 | 329 | return '%s%s[%s]' % (modprefix, qualname, args) |
451 | 330 |
|
452 | 331 | 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